# Lieferando & Takeaway Scraper: Restaurants and Menus (`studio-amba/takeaway-scraper`) Actor

Scrape food delivery restaurants from Lieferando.de, Lieferando.at, Thuisbezorgd.nl, Pyszne.pl and Takeaway.com (Belgium): names, cuisines, ratings, review counts, delivery fees and times, minimum order values, plus full menus with item prices. Search by city or postcode. No login, no cookies.

- **URL**: https://apify.com/studio-amba/takeaway-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** E-commerce
- **Features:** Limited permissions
- **Stats:** 23 total users, 5 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 result scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Lieferando & Takeaway Scraper: Restaurants, Ratings and Menus

Get every restaurant that delivers to a city or postcode on Lieferando.de, Lieferando.at, Thuisbezorgd.nl, Pyszne.pl and Takeaway.com (Belgium). Each row has the name, cuisines, rating, review count, delivery fee, delivery time and minimum order value. Switch on `scrapeMenus` and you also get every dish with its price.

No login and no cookies. Pick a country, type a city, run.

### Why use this actor?

A single run on a big city returns the full restaurant list in under a minute. In our test runs Berlin returned 1,584 restaurants in 60 seconds, Vienna 1,280 in 45 seconds, Amsterdam 930, Warsaw 927 and Brussels 855. Typical uses:

- Delivery fee and minimum order benchmarking per city
- Menu price monitoring across competitors
- Restaurant lead lists per city and cuisine
- Market entry research for a city

### What it covers

| Brand | Country | Input value | Currency |
|-------|---------|-------------|----------|
| Lieferando.de | Germany | `de` | EUR |
| Lieferando.at | Austria | `at` | EUR |
| Thuisbezorgd.nl | Netherlands | `nl` | EUR |
| Pyszne.pl | Poland | `pl` | PLN |
| Takeaway.com | Belgium | `be` | EUR |

All five brands use the same data model, so rows look the same in every country.

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `country` | String | No | `de` (Lieferando.de), `nl` (Thuisbezorgd), `pl` (Pyszne), `be` (Takeaway.com) or `at` (Lieferando.at). Default: `de` |
| `location` | String | No | City name (`Berlin`, `München`, `Warszawa`), postcode (`10115`) or coordinates (`52.52,13.40`). Default: `Berlin` |
| `serviceType` | String | No | `delivery` (default) or `collection` |
| `maxResults` | Integer | No | Maximum restaurants to return (default: 100, maximum: 5000) |
| `scrapeMenus` | Boolean | No | Also fetch each restaurant's full menu, one row per menu item (default: `false`) |
| `proxyConfiguration` | Object | No | Proxy settings. The default works |

City names are matched against a built-in list of the 50 largest places per country. Native names and English names both work (München and Munich, Den Haag and The Hague, Warszawa and Warsaw, Brussel, Bruxelles and Brussels). Postcodes and smaller towns are looked up through OpenStreetMap, and a test with the Belgian town Tienen returned restaurants in Tienen. Coordinates skip the lookup. A location that cannot be found (for example `Qwertzville`) makes the run fail with an error instead of returning an empty dataset.

### Output

One row per restaurant. With `scrapeMenus` enabled, one row per menu item, with the restaurant fields repeated on every row. Rows load straight into a spreadsheet or database.

| Field | Type | Example |
|-------|------|---------|
| `restaurantId` | String | `"10113323"` |
| `name` | String | `"Seydo's Back 'N Späti"` |
| `brand` | String | `"lieferando"` (also `thuisbezorgd`, `pyszne`, `takeaway`) |
| `cuisines` | Array | `["Groceries", "Offers"]` |
| `rating` | Number | `4.6` (0 to 5 scale) |
| `ratingCount` | Integer | `82` |
| `deliveryFee` | Number | `10` |
| `deliveryTimeMinutes` | Integer | `35` |
| `minimumOrderValue` | Number | `30` |
| `currency` | String | `"EUR"` |
| `address` | String | `"Ollenhauerstraße 23"` |
| `city` | String | `"Berlin"` |
| `postcode` | String | `"13403"` |
| `latitude` / `longitude` | Number | `52.568115` / `13.329784` |
| `isOpen` | Boolean | `true` if the restaurant is open at the time of the run |
| `url` | String | Menu page on the brand site |
| `logoUrl` | String | Restaurant logo image |
| `country` | String | `"de"` |
| `serviceType` | String | `"delivery"` or `"collection"` |
| `scrapedAt` | String | ISO timestamp |

Menu rows add `menuCategory`, `itemId`, `itemName`, `itemDescription`, `itemPrice`, `itemVariations` and `itemImageUrl`. `itemVariations` lists the sizes and their prices and is filled only for items that have more than one size. `itemDescription` and `itemImageUrl` are empty on part of the items, because many restaurants do not add them. In a Hamburg run with 12 restaurants, 1,036 of 1,268 menu rows had a description.

### Example output

Restaurant row (`scrapeMenus` off):

```json
{
    "restaurantId": "10113323",
    "name": "Seydo's Back 'N Späti",
    "brand": "lieferando",
    "cuisines": ["Groceries", "Offers"],
    "rating": 4.6,
    "ratingCount": 82,
    "deliveryFee": 10,
    "deliveryTimeMinutes": 35,
    "minimumOrderValue": 30,
    "currency": "EUR",
    "address": "Ollenhauerstraße 23",
    "city": "Berlin",
    "postcode": "13403",
    "latitude": 52.568115,
    "longitude": 13.329784,
    "isOpen": true,
    "url": "https://www.lieferando.de/speisekarte/seydos-back-n-spati",
    "country": "de",
    "serviceType": "delivery",
    "scrapedAt": "2026-10-17T04:00:43.080Z"
}
```

Menu row (`scrapeMenus` on), restaurant fields shortened:

```json
{
    "restaurantId": "13007062",
    "name": "Eni's Burger",
    "brand": "lieferando",
    "city": "Hamburg",
    "menuCategory": "Pizza",
    "itemId": "53ba06b1-c240-4811-8c48-d62aa14b0a0d",
    "itemName": "Pizza Chicken",
    "itemDescription": "mit Hähnchenfilet, Tomatensauce & Käse",
    "itemPrice": 12.99,
    "itemVariations": [
        { "name": "Ø 26cm", "price": 12.99 },
        { "name": "Ø 32cm", "price": 16.99 }
    ]
}
```

### How to scrape Lieferando data

1. Set `country` to `de`.
2. Set `location` to a German city (`Berlin`, `Hamburg`, `München`, `Köln`, `Frankfurt`) or a postcode such as `10115`.
3. Run. Berlin returned 1,584 restaurants.
4. Enable `scrapeMenus` to also get every dish and its price.

The other brands work the same way. Only the `country` value changes.

### How to scrape Thuisbezorgd.nl data

Set `country` to `nl` and `location` to a Dutch city (`Amsterdam`, `Rotterdam`, `Den Haag`, `Utrecht`) or postcode. Amsterdam returned 930 restaurants. Prices are in EUR.

### How to scrape Pyszne.pl data

Set `country` to `pl` and `location` to a Polish city (`Warszawa`, `Kraków`, `Wrocław`, `Gdańsk`). Warsaw returned 927 restaurants. Prices are in PLN.

### How to scrape Takeaway.com Belgium data

Set `country` to `be` and `location` to a Belgian city (`Brussel`, `Antwerpen`, `Gent`, `Liège`). Dutch and French spellings both work. Brussels returned 855 restaurants. Prices are in EUR.

### How to scrape Lieferando.at (Austria) data

Set `country` to `at` and `location` to an Austrian city (`Wien` or `Vienna`, `Graz`, `Linz`, `Salzburg`, `Innsbruck`) or postcode. Vienna returned 1,280 restaurants. Menus work the same as for Germany. Prices are in EUR.

### Menu scraping

With `scrapeMenus` on, every restaurant produces one row per menu item: dish name, description, menu category, price and size variations. `maxResults` still caps the number of restaurants. Menu sizes vary a lot. In test runs, 12 restaurants in Hamburg gave 1,268 rows (from 12 to 500 per restaurant), 8 in Kraków gave 983 rows and 3 in Amsterdam gave 677 rows. Plan for roughly 100 to 125 rows per restaurant on average.

Menu runs take longer than restaurant lists, about 65 seconds for the 3-restaurant Amsterdam run. If the platform moves a long run to another server, it continues where it stopped.

### Tips

- One run covers one delivery point. For full coverage of a large city, run a few postcodes spread across the city and deduplicate on `restaurantId`.
- `isOpen` reflects the moment of the run. A run at 04:00 in Berlin showed 2 of 100 restaurants open, so schedule runs for the hours you care about.
- `serviceType: "collection"` returns restaurants for pickup, and every row carries `serviceType: "collection"`.
- Empty input works. It runs Lieferando.de around Berlin with 100 results.

### Related scrapers

- [Just Eat Scraper](https://apify.com/studio-amba/just-eat-scraper): restaurants from Just Eat in Ireland, Italy and Spain
- [Wolt Scraper](https://apify.com/studio-amba/wolt-scraper): restaurants and menus from Wolt across Northern and Eastern Europe
- [Albert Heijn Scraper](https://apify.com/studio-amba/albert-heijn-scraper): the largest Dutch supermarket
- [Tesco Scraper](https://apify.com/studio-amba/tesco-scraper): full UK grocery catalogue with prices
- [ASDA Scraper](https://apify.com/studio-amba/asda-scraper): UK grocery products and prices
- [Waitrose Scraper](https://apify.com/studio-amba/waitrose-scraper): UK grocery with barcodes
- [Picnic Scraper](https://apify.com/studio-amba/picnic-scraper): Dutch online supermarket

Browse all our European scrapers on the [Studio AMBA profile](https://apify.com/actors/studio-amba).

### Legal

This actor scrapes publicly available data only. It does not log in and does not access personal data. You are responsible for how you use the data, so check the applicable terms and laws for your use case.

### Pricing and cost

The actor charges $0.005 per run start plus $0.002 per dataset row. Restaurant lists are one row per restaurant: Berlin with 1,584 restaurants costs about $3.17, and 100 restaurants cost about $0.21.

With `scrapeMenus` enabled, every menu item is a row. 12 restaurants in Hamburg produced 1,268 rows, about $2.54. At 100 to 125 rows per restaurant, the default `maxResults` of 100 can reach $20 to $25 per run. Set `maxResults` before you enable menus. A run's usage cost only settles after it reports SUCCEEDED.

# Actor input Schema

## `country` (type: `string`):

Which brand to scrape: de = Lieferando.de (Germany), nl = Thuisbezorgd.nl (Netherlands), pl = Pyszne.pl (Poland), be = Takeaway.com (Belgium), at = Lieferando.at (Austria).

## `location` (type: `string`):

Where to search. A city name ('Berlin', 'München', 'Warszawa'), a postcode ('10115'), or literal coordinates ('52.52,13.40'). One search returns every restaurant delivering to that point, roughly 850 to 1,600 in big cities.

## `serviceType` (type: `string`):

Delivery (default) or collection/pickup. Affects which restaurants are returned and their open state.

## `maxResults` (type: `integer`):

Maximum number of restaurants to return. With 'Scrape menus' enabled this is still the restaurant cap. Each restaurant then produces one row per menu item.

## `scrapeMenus` (type: `boolean`):

Also fetch each restaurant's full menu. Output becomes one row per menu item (dish name, description, category, price) with the restaurant fields repeated on every row. Adds two extra requests per restaurant, so runs take longer.

## `proxyConfiguration` (type: `object`):

Proxy settings. The restaurant and menu APIs are open, so the default automatic proxy is plenty.

## Actor input object example

```json
{
  "country": "de",
  "location": "Berlin",
  "serviceType": "delivery",
  "maxResults": 20,
  "scrapeMenus": false,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "location": "Berlin",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/takeaway-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "location": "Berlin",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/takeaway-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "location": "Berlin",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call studio-amba/takeaway-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/takeaway-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/9JrlT23NdcCoy03ez/builds/xccDDhMDlFmXX6ErA/openapi.json
