Lieferando Menu Scraper - Restaurant Menus, Prices & Delivery
Pricing
from $0.70 / 1,000 restaurant or menu results
Lieferando Menu Scraper - Restaurant Menus, Prices & Delivery
Scrape restaurant menus and dish prices from Lieferando.de, Germany's largest food delivery platform: menu, price, delivery fee and minimum order per German postcode, 90-day price history, postcode price matrix and a run-over-run menu change digest. Unofficial, independent tool.
Pricing
from $0.70 / 1,000 restaurant or menu results
Rating
0.0
(0)
Developer
Kamer Ozkan
Maintained by CommunityActor stats
0
Bookmarked
3
Total users
1
Monthly active users
6 days ago
Last modified
Categories
Share
Unofficial Actor: This Actor accesses publicly displayed data from Lieferando.de. It is not affiliated with, endorsed by, or sponsored by Lieferando or Just Eat Takeaway.com.
Lieferando menu scraper and price intelligence for the German food-delivery market: enter German postal codes (or direct menu URLs) and get every restaurant's full menu with dish prices, delivery fee, minimum order, delivery time, rating, opening hours and location as JSON rows - plus the analysis layers a pricing team actually uses: normalized comparable products, a postcode price matrix, 90-day price history and menu inflation per restaurant, and a run-over-run menu change digest (price increases and decreases, new and removed dishes, availability and delivery-term changes).
Built for restaurant chains and franchise operators, delivery-market analysts, food brands, and data teams; it observes public menu pages, never places orders.
What you can build with it
🔔 1. A competitor menu watch that tells you what changed overnight
Add a fixed competitor set as direct menu URLs (or a postcode), schedule the run daily with history and the change digest switched on. Each restaurant is compared with its previous snapshot; the digest lists price increases and decreases with percentages, new and removed dishes, availability flips, and delivery-fee or minimum-order changes, restaurant by restaurant.
{"postalCodes": ["10115"],"maxRestaurantsPerPostalCode": 25,"trackPriceHistory": true,"generateAnalytics": true,"generateChangeDigest": true}
🗺️ 2. A postcode price matrix for the same chain
Run several postal codes and read postcode_price_matrix rows: the same comparable product (size-, quantity- and variant-aware) across branches with min, average, max price and EUR/percent spread. Franchise pricing consistency in one table, exported to CSV.
📈 3. Menu inflation tracking per restaurant
With trackPriceHistory, every menu row carries its 90-day observations and change, and menu_inflation_summary rows report the comparable-basket change per restaurant (unavailable items excluded, not carried at stale prices).
📦 4. Clean menu data for apps, analytics, and AI agents
Menus normalized with German semantic rules (Döner Kebab, Doener Kebap, DONER map to one canonical product), explainable cuisine inference when metadata is missing, and an agent-readable schema: the Actor runs through the Apify API, Make, n8n, and MCP with the same billing.
Menu change digest
Set generateChangeDigest: true (with trackPriceHistory on, the default). The run stores three records in its key-value store once at least one restaurant could be compared or observed for the first time:
| Record | Content |
|---|---|
MENU_CHANGE_DIGEST | JSON: restaurants compared, restaurants with changes, totals (price up/down, new, removed, availability, delivery terms), per-restaurant change lists, next steps |
MENU_CHANGE_DIGEST.html | Printable page with a table per restaurant |
MENU_CHANGE_DIGEST.txt | Plain-text digest for email or Slack |
Restaurants with changes also get a menu_change_summary dataset row (billed as a normal result row). A restaurant's first observation creates its snapshot and is compared from the next run on; run_summary.changeDigest records whether the digest was stored and how it was billed.
Pricing and cost examples
Pay-per-event. Prices below are the FREE-tier rates effective 16 September 2026 (until 15 September 2026 the live price is $0.001 per result row with a negligible start fee). Paid Apify plans get automatic tier discounts of up to 30%. Residential proxy traffic is billed separately by Apify.
| Event | Price | Notes |
|---|---|---|
📄 Result row (result-emitted) | $0.003 ($3 per 1,000) | Menu items, restaurant rows, matrices, inflation summaries, change summaries, run summary |
🔔 Menu change digest (menu-change-digest) | $0.10 | Once per run when requested; priced from 16 September 2026, included free until then |
| ▶️ Actor start | $0.005 per GB | Once per run |
Worked examples at the 16 September prices (before proxy usage):
- One postcode, 2 restaurants, full menus (~80 rows with analytics): ≈ $0.25
- Daily competitor watch, 10 restaurants, ~400 rows, with the change digest: ≈ $1.30 per run → ≈ $39 per month
- Weekly city scan, 3 postcodes x 25 restaurants, ~3,000 rows: ≈ $9 per run → ≈ $39 per month
A failed run produces no result charges; the Actor stops before your maximum charge per run is exceeded.
Related Actors
- HolidayCheck Reviews Scraper - German Hotel Ratings & Trends - German hospitality reviews with aspect trends and competitor sets
- Trusted Shops & ProvenExpert Reviews Scraper - German Ratings - ratings of German businesses, including restaurants and delivery services
- Walmart Product Scraper - Price Tracker & Stock Checker by ZIP - the same change-detection approach for US retail prices
Included intelligence
- complete menu rows with product name, description, category, price, availability, image, and source ID
- delivery fee, minimum order, delivery time, rating, offer, address, coordinates, and opening hours
- published cuisine labels plus explainable menu-based cuisine inference when metadata is missing
- stable chain identity for comparing the same restaurant group across branches
- semantic product normalization that maps spelling variants such as
Döner Kebab,Doener Kebap, andDONER - optional custom alias mappings for market- or brand-specific product language
- size-, quantity-, dietary-, and variant-aware comparable product IDs to avoid false matches
- postcode price matrix with min/average/max price, branches, EUR spread, and percentage spread
- per-item rolling 90-day observations, EUR change, and percentage change
- restaurant-level 90-day menu-basket inflation summaries
- HTML intelligence dashboard plus CSV and JSON exports
- session rotation, blocked-request recovery, run-quality scoring, optional HTTPS alerts, and optional failure on degraded data
Outputs
The default dataset contains six record types:
recordType | Purpose |
|---|---|
menu_item | One current menu product with branch, location, normalization, and 90-day history |
restaurant | Restaurant-level fallback row when menus are disabled or empty |
postcode_price_matrix | Same chain and comparable product summarized across postal codes |
menu_inflation_summary | Current versus first retained comparable menu basket |
menu_change_summary | What changed for one restaurant since its previous snapshot: price moves, new and removed items, availability, delivery terms (only when something changed) |
run_summary | Coverage, failure rates, quality metrics, issues, and final status |
The default key-value store also contains:
REPORT.html- visual executive reportPOSTCODE_PRICE_MATRIX.csv- spreadsheet-ready postcode comparisonANALYTICS.json- matrix and inflation dataRUN_SUMMARY.json- monitoring payloadSCHEDULE_RECOMMENDATION.json- daily production schedule templateMENU_CHANGE_DIGEST/.html/.txt- run-over-run change digest (whengenerateChangeDigestis on)
Example output
All records below are unedited output from live runs on 2026-07-28. The Actor emits
four record types into one dataset: menu_item, postcode_price_matrix,
menu_inflation_summary, and run_summary.
1. A restaurant listing with its live offer (menu_item)
A real Berlin listing: parsed delivery economics (fee, minimum, time window), structured
address and coordinates, cuisine classification with confidence and source, and the
running promotion exactly as the platform shows it. Fields the source does not publish
stay null.
2. Every run audits itself (run_summary and menu_inflation_summary)
The run reports its own quality instead of asking to be trusted: request failure and
retry rates, the share of items with missing prices, cuisine classification coverage,
and exactly how many results were charged. A run that fails its quality thresholds says
so in issues rather than shipping silently bad data.
{"recordType": "run_summary","observedAt": "2026-07-28T12:27:40.624Z","completedAt": "2026-07-28T12:29:09.422Z","status": "healthy","expectedPostalCodes": ["10115"],"resolvedPostalCodes": ["10115"],"requestedRestaurantLimit": 2,"discoveredRestaurantCount": 2,"scrapedRestaurantCount": 2,"menuItemCount": 79,"unavailableItemCount": 7,"matrixRowCount": 72,"crossPostcodeMatrixRowCount": 0,"inflationSummaryCount": 2,"failedRequestCount": 0,"failedRequestRate": 0,"retriedRequestCount": 0,"totalRetryCount": 0,"retryRate": 0,"nullPriceRate": 0,"cuisineCoverage": 1,"averageMenuItemsPerRestaurant": 39.5,"smallMenuRestaurantCount": 0,"issues": [],"failures": [],"chargedResultCount": 79,"stoppedBySpendingLimit": false}
The inflation basket is honest about its composition: unavailable items are excluded from the tracked basket instead of being carried at stale prices, and the record shows that accounting (41 items on the menu, 6 unavailable, 35 tracked).
{"recordType": "menu_inflation_summary","observedAt": "2026-07-28T12:27:40.624Z","searchPostalCode": "10115","chainKey": "lieferando:burgermeister","chainName": "Burgermeister","restaurantName": "Burgermeister Eberswalder","restaurantUrl": "https://www.lieferando.de/en/menu/burgermeister-5?c_id=019f37d0-05cc-7243-9430-de2821818e9a","menuItemCount": 41,"unavailableItemCount": 6,"trackedItemCount": 35,"changedItemCount": 0,"increasedItemCount": 0,"decreasedItemCount": 0,"unchangedItemCount": 35,"currentComparableBasket": 267.84,"firstComparableBasket": 267.84,"menuInflation90d": 0,"medianItemChangePercent90d": 0,"maxItemIncreasePercent90d": null,"maxItemDecreasePercent90d": null}
3. Cross-postcode price comparison (postcode_price_matrix)
The same comparable product is matched across postcodes with per-postcode min, average, and max plus the contributing branches. In this real observation both areas were served at identical prices, so the spread is reported as exactly zero: the matrix reports no difference when there is none, which is what makes a nonzero spread trustworthy.
Pricing
See "Pricing and cost examples" at the top of this page: one result-emitted event per delivered row (menu items, matrices, summaries and change summaries alike), a small Actor start fee, and the optional menu-change-digest event once per run when requested. A failed run produces no result charges.
This Actor is also exposed to AI agents through Apify's MCP server (mcp.apify.com): an agent can discover it by search and run it with the same pay-per-event billing, with no separate integration.
Run locally
npm installnpm run typechecknpm testnpm run buildnpm start
Copy examples/production-input.json to storage/key_value_stores/default/INPUT.json before npm start. For a short smoke test, reduce postalCodes to one value and maxRestaurantsPerPostalCode to 1.
Production use
Use the input in examples/production-input.json, keep the same named key-value store between runs, and create a daily Apify schedule. Full scheduling, alerting, output, and retention guidance is in docs/production.md.
For a fixed competitor set, add Lieferando menu URLs to restaurantUrls. Direct URLs can be collected without a search-postcode context, but postcode matrices require postcode-routed discovery.
Lieferando blocks data-center and direct Apify cloud IPs. The Actor therefore defaults to a German residential Apify Proxy profile, which is billed separately by Apify. The proxy settings remain visible and editable in the Actor input.
Comparison behavior
canonicalProductId represents the normalized semantic product. comparableProductId adds size, quantity, dietary, and variant attributes, so a 0.33 L cola is not compared with a 1 L cola.
Matrix rows are keyed by chain plus comparableProductId. A cross-postcode match therefore requires at least two input postal codes and an overlapping chain/product combination. Every source branch remains listed in the matrix cell for auditability.
Price history is keyed by postal code, branch, and Lieferando source product ID in the named store lieferando-price-history-v1. Repeated runs retain 90 days and append at most one unchanged observation per day. A first run has no earlier baseline, so change fields remain null until a later run supplies one.
customProductAliases can extend the built-in German rules without a code change. Aliases are applied safely as normalized phrases; size and quantity safeguards remain part of comparableProductId.
Publish
The Actor definition, Store README, deterministic Docker build, input/output schemas, dataset view, resource limits, and changelog are included. Deploy the folder with apify push or connect it as the Actor source in Apify Console, complete the account-owned Store display fields, and click Publish to Store.
Responsible operation
Use conservative concurrency, respect applicable law and platform terms, and avoid collecting personal or account data. The Actor only reads publicly displayed restaurant and menu information.