Foodora Scraper | Restaurants, Menus, Reviews & Offers avatar

Foodora Scraper | Restaurants, Menus, Reviews & Offers

Pricing

from $2.20 / 1,000 results

Go to Apify Store
Foodora Scraper | Restaurants, Menus, Reviews & Offers

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

kane liu

Maintained by Community

Actor stats

1

Bookmarked

10

Total users

4

Monthly active users

a day ago

Last modified

Security

Limited permissions

Share

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, shops and chain return restaurant or shop rows around a location.
  • Restaurant details: restaurant returns one restaurant, with optional menu, review and offer rows.
  • Keyword search: searchKeyword finds matching restaurants around a location, not every restaurant in a country.
  • Discovery: discoverCities, discoverCuisines and enumerateRestaurants return city, cuisine or restaurant rows.
  • Several URLs: startUrls accepts 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

FieldDescriptionExample
rowTypeEntity represented by the rowrestaurant
vendorCodeFoodora restaurant identifiertu8l
nameRestaurant nameExample Pizza
urlRestaurant pagehttps://www.foodora.no/restaurant/tu8l/perfetto-yalla
marketCountry codeno
ratingSource rating, when available4.5
restaurantAddressRestaurant addressExample Street 1, Oslo
locationResolutionActual location used and whether it was broadened{"name":"Oslo","relaxed":false}
FieldDescriptionExample
productIdDish identifierexample-product-1
nameDish nameMargherita
categoryNameMenu categoryPizza
priceCurrent price, including a discount when applicable149
originalPricePrice before a discount, when shown169
currencyCurrency codeNOK
productVariationsAvailable sizes or variants; at most 50[{"name":"Large","price":179}]
restaurantIdParent restaurant identifiertu8l

City rows

FieldDescriptionExample
citySlugCity key for later inputsoslo
nameCity nameOslo
marketCountry codeno

Cuisine rows

FieldDescriptionExample
cuisineSlugCuisine key for later inputspizza
nameSource cuisine labelPizza
citySlugCity whose cuisine list was returnedoslo

Review rows

FieldDescriptionExample
reviewIdReview identifierexample-review-1
vendorCodeReviewed restauranttu8l
textPublic review text, possibly emptyExample review text
createdAtSource review date2026-10-01T12:00:00Z

Offer rows

FieldDescriptionExample
offerIdOffer identifierexample-offer-1
titleOffer labelExample discount
valueAmount interpreted with valueType10
termsAndConditionsConditions shown for the offer["Selected dishes only"]

How to scrape Foodora

  1. Open Foodora Scraper in Apify Console.
  2. Choose market and fill a target such as citySlug, cuisineSlug or restaurantUrl.
  3. Start with maxResults: 5; enable extra row types only if needed.
  4. Click Start, then check the dataset and run status.
  5. 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.

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

FieldWhat to enterDefault
modeauto or a mode described aboveauto
marketno, se, at, hu, czno
citySlugCity key or place nameEmpty; form example oslo
cuisineSlugCuisine key such as pizzaEmpty; form example pizza
restaurantUrlSupported Foodora restaurant linkEmpty
vendorCodeShort code from a restaurant linkEmpty
vendorSlugRestaurant name part of the URL, if neededEmpty
chainNameBrand or chain nameEmpty
searchKeywordRestaurant search termEmpty
startUrlsList of supported Foodora linksEmpty
maxResultsMaximum rows per input, 1–50070; form example 3
includeMenuItemsAdd separate dish rowsfalse
maxMenuItemsPerRestaurantDish-row cap per restaurant, 0–20020
menuKeywordOptional dish search within a restaurantEmpty
includeToppingsRetain available topping identifierstrue
includeReviewsAdd restaurant review rowsfalse
includeOffersAdd restaurant offer rowsfalse
enrichMenusAdd menus after listings; also enable includeMenuItemsfalse
maxEnrichMaximum restaurants to enrich, 0–505
verticalrestaurants, shops, groceries, pharmacy, retailrestaurants
openingTypedelivery, pickup, dine_indelivery
latitude, longitudeDecimal coordinates as stringsLocation-derived
langLanguage prefix used in page linksen
localeOptional country hint such as sv-SEEmpty
loadMoreRoundsExtra listing expansion rounds where supported, 0–200
cursorContinuation object; normally leave emptyEmpty
proxyCountryNormally leave empty to follow the marketMarket 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 planStart fee at 512 MBPrice per rowPrice 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
  • maxResults applies to each URL in startUrls, 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 (maxTotalChargeUsd in 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 ApifyClient
client = 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

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.

More food delivery and grocery scrapers from the same publisher:

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.