Foodora Scraper | Restaurants, Menus, Reviews & Offers
Pricing
from $2.20 / 1,000 results
Foodora Scraper | Restaurants, Menus, Reviews & Offers
Extract Foodora restaurants, menu prices, reviews and offers in Norway, Sweden, Austria, Hungary and Czechia. Search by location, cuisine or chain, and export rows. Pay per delivered row plus a start fee.
Pricing
from $2.20 / 1,000 results
Rating
0.0
(0)
Developer
kane liu
Maintained by CommunityActor stats
1
Bookmarked
10
Total users
4
Monthly active users
a day ago
Last modified
Categories
Security
Limited permissionsShare
Foodora Scraper
Extract Foodora restaurants, menu prices, reviews and offers in Norway, Sweden, Austria, Hungary and Czechia as exportable rows.
- Find restaurants by city, cuisine, chain or keyword.
- Add individual menu items, reviews and offers when needed.
- Discover city and cuisine slugs, or collect restaurant catalog entries.
- Export rows or use them through the Apify API and MCP server.
- Pay $3.00 per 1,000 rows on the Free plan, plus a start fee.
What does Foodora Scraper do?
Foodora Scraper collects public data from foodora.no, foodora.se, foodora.at, foodora.hu and foodora.cz. Use it to compare menus, build restaurant lists or track available offers. It is unofficial and is not affiliated with Foodora or Delivery Hero.
- Listings:
cuisine,city,shopsandchainreturn restaurant or shop rows around a location. - Restaurant details:
restaurantreturns one restaurant, with optional menu, review and offer rows. - Keyword search:
searchKeywordfinds matching restaurants around a location, not every restaurant in a country. - Discovery:
discoverCities,discoverCuisinesandenumerateRestaurantsreturn city, cuisine or restaurant rows. - Several URLs:
startUrlsaccepts restaurant, city and cuisine links.
includeMenuItems, includeReviews, includeOffers and enrichMenus are off by default. Each added menu item, review or offer is a separate row, billed at the same rate as a restaurant row. These rows share the input's row limit.
What data can you extract from Foodora?
Fields vary by mode and source availability. rowType distinguishes restaurant, menuItem, city, cuisine, review and offer. Shops and chain outlets use restaurant rows. The following values illustrate the format; they are not a live capture.
Restaurant rows
| Field | Description | Example |
|---|---|---|
rowType | Entity represented by the row | restaurant |
vendorCode | Foodora restaurant identifier | tu8l |
name | Restaurant name | Example Pizza |
url | Restaurant page | https://www.foodora.no/restaurant/tu8l/perfetto-yalla |
market | Country code | no |
rating | Source rating, when available | 4.5 |
restaurantAddress | Restaurant address | Example Street 1, Oslo |
locationResolution | Actual location used and whether it was broadened | {"name":"Oslo","relaxed":false} |
Menu item rows
| Field | Description | Example |
|---|---|---|
productId | Dish identifier | example-product-1 |
name | Dish name | Margherita |
categoryName | Menu category | Pizza |
price | Current price, including a discount when applicable | 149 |
originalPrice | Price before a discount, when shown | 169 |
currency | Currency code | NOK |
productVariations | Available sizes or variants; at most 50 | [{"name":"Large","price":179}] |
restaurantId | Parent restaurant identifier | tu8l |
City rows
| Field | Description | Example |
|---|---|---|
citySlug | City key for later inputs | oslo |
name | City name | Oslo |
market | Country code | no |
Cuisine rows
| Field | Description | Example |
|---|---|---|
cuisineSlug | Cuisine key for later inputs | pizza |
name | Source cuisine label | Pizza |
citySlug | City whose cuisine list was returned | oslo |
Review rows
| Field | Description | Example |
|---|---|---|
reviewId | Review identifier | example-review-1 |
vendorCode | Reviewed restaurant | tu8l |
text | Public review text, possibly empty | Example review text |
createdAt | Source review date | 2026-10-01T12:00:00Z |
Offer rows
| Field | Description | Example |
|---|---|---|
offerId | Offer identifier | example-offer-1 |
title | Offer label | Example discount |
value | Amount interpreted with valueType | 10 |
termsAndConditions | Conditions shown for the offer | ["Selected dishes only"] |
How to scrape Foodora
- Open Foodora Scraper in Apify Console.
- Choose
marketand fill a target such ascitySlug,cuisineSlugorrestaurantUrl. - Start with
maxResults: 5; enable extra row types only if needed. - Click Start, then check the dataset and run status.
- Download the rows or read them through the API.
An empty input runs the form's Oslo pizza example with at most 3 rows. Example rows are charged normally. With mode: "auto", a filled target selects the mode. If targets conflict, priority is startUrls, restaurantUrl, vendorCode, chainName, searchKeyword, cuisineSlug, then citySlug. INPUT_REPORT records the choice.
Cuisine
Fill cuisineSlug, optionally with citySlug. Without a city, the selected market's capital is used.
Restaurant
Fill restaurantUrl or vendorCode. Enable includeMenuItems for dish rows. menuKeyword narrows the dishes; includeReviews and includeOffers request those extra rows.
City
Fill citySlug for nearby restaurants. A city input is location-based, not a guarantee of every outlet inside its administrative boundary.
Shops
Choose mode: "shops" and fill citySlug. Availability depends on the location and selected vertical.
Discover cities
Choose discoverCities and a market. Returned city keys can be reused as citySlug; this is not an exhaustive city directory.
Discover cuisines
Choose discoverCuisines and optionally a city. Without one, the market capital is used. Reuse a returned cuisineSlug for a listing.
Chain
Fill chainName, optionally with citySlug. Without a city, the capital is used. Matching depends on the chain and restaurant names available from Foodora.
Keyword search
Fill searchKeyword. Add a city or coordinates for the area; without them, the search uses the market capital.
Start URLs
Supply a startUrls list of supported Foodora links. Each URL is one input with its own row limit.
Enumerate restaurants
Choose enumerateRestaurants and a market, without a city or cuisine. It returns restaurant details for available catalog entries and skips entries whose details cannot be obtained.
What to fill in
| Field | What to enter | Default |
|---|---|---|
mode | auto or a mode described above | auto |
market | no, se, at, hu, cz | no |
citySlug | City key or place name | Empty; form example oslo |
cuisineSlug | Cuisine key such as pizza | Empty; form example pizza |
restaurantUrl | Supported Foodora restaurant link | Empty |
vendorCode | Short code from a restaurant link | Empty |
vendorSlug | Restaurant name part of the URL, if needed | Empty |
chainName | Brand or chain name | Empty |
searchKeyword | Restaurant search term | Empty |
startUrls | List of supported Foodora links | Empty |
maxResults | Maximum rows per input, 1–500 | 70; form example 3 |
includeMenuItems | Add separate dish rows | false |
maxMenuItemsPerRestaurant | Dish-row cap per restaurant, 0–200 | 20 |
menuKeyword | Optional dish search within a restaurant | Empty |
includeToppings | Retain available topping identifiers | true |
includeReviews | Add restaurant review rows | false |
includeOffers | Add restaurant offer rows | false |
enrichMenus | Add menus after listings; also enable includeMenuItems | false |
maxEnrich | Maximum restaurants to enrich, 0–50 | 5 |
vertical | restaurants, shops, groceries, pharmacy, retail | restaurants |
openingType | delivery, pickup, dine_in | delivery |
latitude, longitude | Decimal coordinates as strings | Location-derived |
lang | Language prefix used in page links | en |
locale | Optional country hint such as sv-SE | Empty |
loadMoreRounds | Extra listing expansion rounds where supported, 0–20 | 0 |
cursor | Continuation object; normally leave empty | Empty |
proxyCountry | Normally leave empty to follow the market | Market country |
Examples below request small outputs. The first also demonstrates auto selection.
Cuisine
{"market":"no","citySlug":"oslo","cuisineSlug":"pizza","maxResults":5}
Restaurant with menu items
{"mode":"restaurant","market":"no","vendorCode":"tu8l","includeMenuItems":true,"maxResults":5}
City
{"mode":"city","market":"se","citySlug":"stockholm","maxResults":5}
Shops
{"mode":"shops","market":"no","citySlug":"oslo","vertical":"shops","maxResults":5}
Discover cities
{"mode":"discoverCities","market":"no","maxResults":3}
Discover cuisines
{"mode":"discoverCuisines","market":"hu","citySlug":"budapest","maxResults":3}
Chain
{"mode":"chain","market":"no","citySlug":"oslo","chainName":"McDonald","maxResults":3}
Keyword search
{"mode":"searchKeyword","market":"se","citySlug":"stockholm","searchKeyword":"pizza","maxResults":5}
Start URLs
{"startUrls":["https://www.foodora.no/restaurant/tu8l/perfetto-yalla"],"maxResults":3}
Enumerate restaurants
{"mode":"enumerateRestaurants","market":"no","maxResults":3}
maxItems and limit are accepted aliases for maxResults. Unknown fields do not fail input resolution: close misspellings may be corrected; other fields are ignored with a note. Check INPUT_REPORT in the default key-value store for filled, corrected or ignored fields. INPUT_ECHO shows the interpreted input.
Invalid targets or values that cannot be used stop before row charges, with a message such as INVALID_INPUT: market — use one of no, se, at, hu, cz. Invalid filters can instead fall back to their defaults with a warning. The start fee still applies.
Output example
Illustrative menu row, not a current quote:
{"rowType": "menuItem","itemType": "menu_product","productId": "example-product-1","name": "Margherita","categoryName": "Pizza","price": 149,"originalPrice": 169,"currency": "NOK","vendorCode": "tu8l","restaurantId": "tu8l","restaurantName": "Example Pizza","restaurantUrl": "https://www.foodora.no/restaurant/tu8l/perfetto-yalla","market": "no"}
Export the dataset as JSON, CSV, Excel, XML, RSS or an HTML table. JSON preserves nested variant and location information. RUN_SUMMARY records delivered counts and warnings; failed runs can also write ERROR_SUMMARY.
Why use this Foodora scraper?
- Pay per delivered row. Restaurant and optional child rows use the same price, plus the start fee.
- Keep available results. Rows already written remain in the dataset. When an early-ending run returns partial results, the Actor can deliver them; a forced abort does not guarantee recovery of unfinished collection.
- Inspect failures. Input reports and error summaries help distinguish a bad input from a collection failure.
- See missing values. Unavailable source details remain absent or empty rather than being presented as verified facts.
- Reuse identifiers. Menu rows retain restaurant linkage, and discovery rows provide keys for later runs.
- No proxy setup. You do not need to set up proxies.
How much does it cost to scrape Foodora?
The Actor uses pay-per-event pricing. The start event costs $0.005 per GB of allocated memory, with a minimum of one event. At the default 512 MB, the start fee is $0.005. Platform usage is included in these prices.
| Apify plan | Start fee at 512 MB | Price per row | Price per 1,000 rows |
|---|---|---|---|
| Free | $0.005 | $0.003 | $3.00 |
| Starter | $0.005 | $0.003 | $3.00 |
| Scale | $0.005 | $0.0026 | $2.60 |
| Business | $0.005 | $0.0022 | $2.20 |
| Platinum | $0.005 | $0.002 | $2.00 |
| Diamond | $0.005 | $0.0016 | $1.60 |
maxResultsapplies to each URL instartUrls, or the single input in other modes. It defaults to 70; larger requests are collected in parts of 70, up to the input maximum of 500.- Restaurant, menu, review, offer and discovery rows share that limit. Requesting five rows does not mean five restaurants plus their dishes.
- Free Apify plan runs are capped at 200 rows. This Actor also has a 10-run allowance for Free-plan users, enforced when per-user usage can be determined.
- Set Maximum cost per run (
maxTotalChargeUsdin the API) to cap the whole run. Collection can return fewer rows than requested.
Example: five delivered rows on the Free plan at 512 MB cost 5 × $0.003 + $0.005 = $0.020. A run with no delivered rows has no row charges, but still incurs its start fee.
What happens when the run timeout is too short
When a run is close to its time limit, it can save its collection job and pause with an ABORTED status instead of starting the same work again. If continuation is available for that run, it resumes the saved job and delivers the remaining rows. Rows already stored in the dataset are not pushed or charged again by the delivery step.
Check the status message to distinguish this planned pause from a manual abort or a failed run. A manual abort does not guarantee continuation. Use a longer timeout for large requests, and check RUN_SUMMARY for partial results or a continuation cursor.
Use with AI agents and the API
Apify MCP server
Add this tool in a remote MCP client such as Claude, ChatGPT, Cursor or VS Code:
https://mcp.apify.com?tools=lentic_clockss/foodora-scraper
Sign in with Apify through OAuth when prompted, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool starts a run and returns run and dataset IDs; the agent reads rows with get-dataset-items.
Clients without remote MCP support can use npx @apify/actors-mcp-server --tools lentic_clockss/foodora-scraper with APIFY_TOKEN set.
Example prompt: “Find five pizza restaurants in Oslo with Foodora Scraper, using market: no, citySlug: oslo, cuisineSlug: pizza and maxResults: 5.”
Apify API
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("lentic_clockss/foodora-scraper").call(run_input={"market": "no", "citySlug": "oslo", "cuisineSlug": "pizza", "maxResults": 5})for row in client.dataset(run["defaultDatasetId"]).iterate_items():print(row)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('lentic_clockss/foodora-scraper').call({market: 'no', citySlug: 'oslo', cuisineSlug: 'pizza', maxResults: 5});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
For HTTP, send the input JSON to POST https://api.apify.com/v2/acts/lentic_clockss~foodora-scraper/runs with the same authorization header. After completion, read GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json using the run's defaultDatasetId.
Integrations
Use the Actor's Integrations tab to connect results to Google Sheets, Make, Zapier, n8n, Slack, Airtable or a webhook. Use Apify Schedules for recurring runs.
FAQ
Is it legal to scrape Foodora?
Use public data responsibly. You are responsible for checking site terms and applicable data protection law. Processing personal data requires a lawful basis; public visibility alone does not establish permission for every use.
Why did my run end as ABORTED?
A run can be stopped by you or another caller. Check its log and status message. Already delivered rows remain in the dataset, but an aborted run does not promise automatic continuation or delivery of unfinished work.
How many results can I get?
Set maxResults from 1 to 500 per input. The default is 70, while an empty-input example requests at most 3. Free-plan and maximum-cost limits can reduce the total, as can source availability.
Why are some fields empty?
Foodora does not supply every field for every restaurant or market. An omitted menuAvailable is not proof of an empty menu; it can mean the menu was not observed or no dish matched menuKeyword.
Which place names can I use?
Use local city keys such as wien, praha and goteborg. Aliases vienna, prague and gothenburg are mapped automatically. Districts, postal codes and regions can also be resolved; inspect locationResolution to see whether a broader area was used.
Why did I get fewer menu items than expected?
The restaurant row and any reviews or offers consume the same limit as dishes. maxMenuItemsPerRestaurant adds a separate dish cap, default 20. Increase the relevant limits or disable unneeded row types. menuTruncated signals that more dishes were available than loaded.
Does this collect a whole country's restaurants?
Location-based listings and keyword searches do not guarantee national coverage. enumerateRestaurants follows the public restaurant catalog, still subject to availability and row limits. Unavailable restaurant details are skipped.
Does this support Foodpanda or Foodora Finland?
No. This Actor supports only the five listed Foodora markets, not Foodpanda, foodora.fi or the foodora.com brand portal.
Limitations
- Listings depend on location, service type and source availability; shops may have limited coverage.
- Complete menus, all cities, all reviews and every offer are not guaranteed.
- Dish variants are capped at 50. Prices and availability can change after collection.
- Checkout, payments, private account data and order history are outside scope.
- A broadened location must not be treated as an exact match to the requested district or postal code.
Related scrapers
More food delivery and grocery scrapers from the same publisher:
- Grab Scraper
- iFood Scraper
- PedidosYa Scraper
- Uber Eats Scraper
- Deliveroo Scraper
- Foodpanda Scraper
- DoorDash Scraper
- Rappi Scraper
Browse all of our scrapers at apify.com/lentic_clockss.
Support
Report a problem or request a field through the Issues tab of this Actor's page. Include the run ID and the input you used.