# TheFork Scraper \[$1.5/1k💰] | Restaurant Leads & Reviews (`ahmed_jasarevic/thefork-scraper`) Actor

Scrape restaurants, reviews, menus and prices from TheFork.com (TripAdvisor's European reservation platform): name, cuisine, price, rating, review text, geolocation and bookability for restaurant lead generation and hospitality market research.

- **URL**: https://apify.com/ahmed\_jasarevic/thefork-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.40 / 1,000 restaurants

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## TheFork Restaurant Scraper

Scrape **restaurants, reviews, menus & prices from TheFork.com** — TripAdvisor's European restaurant-reservation platform — for **restaurant lead generation and hospitality market research** across France, Italy, Spain, UK, Germany and more. Paste a city page or a restaurant page; get structured JSON/CSV/Excel rows. No login required.

### Main Use Cases

- **Restaurant lead generation** — build clean lists of restaurants per European city with address, geo-coordinates, cuisine, price level and bookability.
- **Hospitality market research** — track TheFork ratings (0–10), review counts and price positioning across cities and countries (EU-heavy: France, Italy, Spain, UK, Germany...).
- **Restaurant review monitoring** — capture review texts, reviewer names, ratings and meal dates for reputation monitoring and sentiment analysis.
- **Menu & price benchmarking** — scrape menus with sections and items, average prices and price-range levels for competitive restaurant analysis.
- **Export for SaaS & dashboards** — pipe reviews into a review-monitoring product or a hospitality dataset via the Apify API.

### How It Works

TheFork's HTML site sits behind **DataDome** anti-bot — but its mobile apps talk to an open **GraphQL API** (`api.thefork.com/graphql`) that returns fully structured restaurant data. This actor speaks that API directly: city/search pages are resolved through `searchRestaurant` (25 restaurants per page, server-side pagination), and restaurant details (`description`, chef, phone, menus, TripAdvisor ratings, photo gallery, bookable time slots) plus full **review texts** come from the same proxy-free API. No browser, no HTML parsing, **no proxy needed** — fast and cheap.

### Build European Restaurant Lead Lists Without an Official TheFork API

TheFork has no public API for restaurant listings. This actor returns the full structured dataset instead: name, address (street/locality/zip/country), geolocation, cuisine, price range, average price, TheFork rating & review count, tags, photos, bookability — every field a hospitality lead-gen or analytics pipeline needs, from a single city URL.

### Track Restaurant Reviews & Ratings Across Cities

Detail rows include the full review list (`reviews`: text, rating, reviewer, meal date) and TripAdvisor scores — and with `scrapeReviews` on, each review is also written as its own row to a separate **reviews** dataset for bulk sentiment analysis. Schedule weekly runs to monitor rating changes and new reviews for the restaurants that matter to you.

### Input

| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
| `startUrls` | array | No | London city page | TheFork city/search pages (e.g. `https://www.thefork.com/restaurants/london-c665790`) and/or restaurant pages (e.g. `https://www.thefork.com/restaurant/the-lanesborough-grill-r597933`). Cuisine/area/tag pages under `/restaurants/...` also work. City pages paginate automatically (25/page). |
| `scrapeDetails` | boolean | No | `false` | Also fetch each restaurant's detail data: description, chef name, phone, menus (sections + items + prices), review texts, TripAdvisor ratings, bookable slots, photo gallery. |
| `scrapeReviews` | boolean | No | `false` | Also store each review as its own row in a separate **reviews** dataset (implies `scrapeDetails`). Each review is a pay-per-event charge. |
| `maxReviewsPerRestaurant` | integer | No | `50` | Cap on reviews fetched per restaurant (1–500), applied whenever details are on. API returns 25 reviews/page, paginated automatically. |
| `maxItems` | integer | No | `100` | Hard cap on restaurant rows for the whole run (max 5000). |
| `maxItemsPerSearch` | integer | No | `200` | Cap per city/search URL. |

### Example Input

```json
{
  "startUrls": [{ "url": "https://www.thefork.com/restaurants/london-c665790" }],
  "scrapeDetails": true,
  "scrapeReviews": true,
  "maxReviewsPerRestaurant": 50,
  "maxItems": 100
}
```

### Output

Two datasets: **restaurants** (default) and **reviews** (separate, when `scrapeReviews` is on).

#### Restaurant row (search)

```json
{
  "name": "Hans' Bar and Grill",
  "url": "https://www.thefork.com/restaurant/hans-bar-and-grill-r815695",
  "cuisine": "British",
  "priceRange": "€€",
  "priceRangeLevel": 2,
  "avgPrice": 30,
  "currency": "GBP",
  "rating": 9.4,
  "reviewCount": 591,
  "address": { "street": "11 Cadogan Gardens", "locality": "London", "zipCode": "SW3 2RJ", "country": "United Kingdom" },
  "geolocation": { "latitude": 51.49357, "longitude": -0.15922 },
  "isBookable": true,
  "tags": ["American Express", "Visa", "British", "Chelsea"],
  "photos": ["https://cdn.thefork.com/tf-lab/image/upload/restaurant/..."],
  "source": "search",
  "sourceUrl": "https://www.thefork.com/restaurants/london-c665790",
  "scrapedAt": "2026-09-21T09:28:00.000Z"
}
```

Detail rows (`source: "detail"`) additionally include `description`, `chefName`, `foodRequirements`, `paymentAccepted`, `openingHours`, `menus` (sections + items + prices), `reviews` (text, rating, reviewer, date) and the full photo gallery.

#### Dataset schema (default dataset — `overview` view)

`name`, `cuisine`, `priceRange`, `avgPrice`, `rating`, `reviewCount`, `address`, `geolocation`, `url`, `source`

#### Review row (reviews dataset)

| Field | Description |
|---|---|
| `restaurantName`, `restaurantUrl` | Parent restaurant identity |
| `rating` | Review score (0–10) |
| `text` | Review body |
| `mealDate` | Date of the meal |
| `reviewerUsername`, `reviewerReviewCount` | Reviewer profile data |
| `likes` | Up-vote count |
| `restaurantReply` | Owner reply text |
| `publicationStatus` | e.g. `PUBLISHED` |
| `photos` | Images attached to the review |

```json
{
  "restaurantId": "6c1651d7-0442-4117-98a0-529d1ca06220",
  "restaurantName": "Hans' Bar and Grill",
  "reviewId": "fad91300-6a64-40d2-830b-06890675a086",
  "rating": 9,
  "mealDate": "2026-09-17T18:45:00.000Z",
  "text": "Nice experience in a very luxurious restaurant's hotel.",
  "publicationStatus": "PUBLISHED",
  "reviewerUsername": "Davide T."
}
```

Download either dataset as JSON, HTML, CSV or Excel.

### Scrape Restaurant Menus & Prices for Competitive Benchmarking

Detail rows carry `menus` (sections → items) and the budget signal from `avgPrice` + `priceRange` (€…€€€€). Compare price positioning and menu structure across an entire city or cuisine segment — the dataset a hospitality consultancy would pay for.

### Integrations & Automation

- **Apify API** — feed restaurant/review rows into your CRM, SaaS or dashboard.
- **Webhooks** — get notified when a monitored scraped run finishes.
- **Scheduling** — weekly rating/review monitoring, monthly market snapshots.
- **Export** — JSON, CSV, HTML, Excel.

*Recommended schedule:* **weekly** for review/rating monitoring; **monthly** for full market research sweeps.

### Related Actors

- [TheFork Scraper - Restaurants, Reviews & Menus](https://apify.com/clearpath/thefork-scraper) — clearpath's TheFork scraper (100+ fields, cluster leading user count).
- [TheFork Restaurant Intelligence Scrapper](https://apify.com/jdtpnjtp/thefork-restaurant-scraper-advanced) — enterprise-grade TheFork extraction across 11 EU countries.
- [TheFork Restaurant Reviews Scraper - Multi-Language](https://apify.com/clearpath/thefork-restaurant-reviews) — dedicated multi-language TheFork review extraction.
- [TheFork Restaurant Scraper - Reviews, Prices & Menus](https://apify.com/memo23/thefork-restaurant-scraper) — paste-a-URL TheFork restaurant scraper.
- [TheFork Scraper — European Restaurant Listings & Prices](https://apify.com/studio-amba/thefork-scraper) — city-based TheFork listing scraper.

### FAQ

#### Why use this actor instead of the official TheFork API?

There is no public TheFork API. This actor calls the open mobile GraphQL endpoint (`api.thefork.com/graphql`) that powers the TheFork mobile apps — so you get fully structured restaurant and review data (name, cuisine, rating, menu, geo, photos) without a browser, HTML parsing, or API credentials.

#### What are alternatives to this actor / restaurant data for Europe?

- [clearpath/thefork-scraper](https://apify.com/clearpath/thefork-scraper) — 100+ fields, more expensive ($0.0055/restaurant).
- [jdtpnjtp/thefork-restaurant-scraper-advanced](https://apify.com/jdtpnjtp/thefork-restaurant-scraper-advanced) — 11-country enterprise TheFork data.
- [memo23/thefork-restaurant-scraper](https://apify.com/memo23/thefork-restaurant-scraper) — similar paste-a-URL approach.

#### How can I get all restaurants in a city?

Paste the city page URL (e.g. `https://www.thefork.com/restaurants/paris-c415144`) into `startUrls` and set `maxItems` up to 5000. The actor paginates automatically (25/page) through the whole result set.

#### What is the best way to monitor restaurant reviews over time?

Run weekly with `scrapeReviews: true` and `maxReviewsPerRestaurant` capped (e.g. 25). Review rows land in the separate reviews dataset with meal dates, so you can diff for new reviews and rating changes.

#### Does this actor need a proxy?

No. Both the search and detail paths run proxy-free against TheFork's mobile GraphQL API (which even bypasses the DataDome challenge — no browser, no HTML).

### For AI Agents & LLM Apps

- **Purpose:** returns one structured restaurant record per TheFork city/search/restaurant page (name, address, geolocation, cuisine, price range, average price, rating, review count, bookability — plus menus, review texts and TripAdvisor scores when `scrapeDetails` is on).
- **Minimal input:**

```json
{ "startUrls": [{ "url": "https://www.thefork.com/restaurants/london-c665790" }], "maxItems": 50 }
```

- **Variant — full details + reviews:**

```json
{
  "startUrls": [{ "url": "https://www.thefork.com/restaurants/paris-c415144" }],
  "scrapeDetails": true,
  "scrapeReviews": true,
  "maxReviewsPerRestaurant": 25,
  "maxItems": 100
}
```

- **Output field list (default dataset):** `name`, `url`, `cuisine`, `priceRange`, `priceRangeLevel`, `avgPrice`, `currency`, `rating`, `reviewCount`, `address`, `geolocation`, `isBookable`, `tags`, `highlightedTags`, `photos`, `source`, `sourceUrl`, `scrapedAt`. Detail rows add `description`, `chefName`, `foodRequirements`, `paymentAccepted`, `openingHours`, `menus`, `reviews`, `tripadvisorRating`, `tripadvisorReviewCount`. Separately: `reviews` dataset rows (`restaurantName`, `rating`, `text`, `mealDate`, `reviewerUsername`, `likes`, `publicationStatus`...).

Behaviors an agent should know:

- `startUrls` accept both city/search pages (paginated, 25/page) and single restaurant pages (one full row).
- `scrapeReviews` **implies** `scrapeDetails`; each review row in the separate dataset is an extra pay-per-event charge.
- `maxItems` is the hard cap for the whole run (max 5000); `maxItemsPerSearch` caps per city URL.
- **No proxy input exists** — the actor is inherently proxy-free (mobile GraphQL API); do not pass proxy config.
- Menu item row includes per-item names, but a single per-preset price is what the API exposes (per-item prices are not available).
- **Billing:** pay-per-event — `restaurant` $0.0015/row, `additional data` $0.001 (contact + extra details), `review` $0.0015/row.

### Legal & Compliance Disclaimer

This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by TheFork, TripAdvisor, or La Fourchette SAS. It reads only publicly available restaurant and review data from TheFork's public pages and open mobile API — no login bypass. Users are responsible for complying with TheFork's Terms of Service and applicable data-protection law (e.g. GDPR for EU restaurant and reviewer data). Contact details returned (phone where published) should not be used for unsolicited commercial outreach in violation of applicable anti-spam rules.

### SEO Keywords

thefork scraper, restaurant data europe, restaurant scraping, thefork api alternative, restaurant lead generation, hospitality market research, restaurant reviews data, thefork reviews, restaurant price data, restaurant menu scraping, tripadvisor thefork data, restaurant database, restaurant ratings data, thefork restaurants paris, thefork restaurants london, restaurant market intelligence, restaurant sentiment analysis, european restaurant data, restaurant geolocation data, restaurant booking data

# Actor input Schema

## `startUrls` (type: `array`):

Paste TheFork city/search pages (e.g. https://www.thefork.com/restaurants/london-c665790) and/or restaurant pages (e.g. https://www.thefork.com/restaurant/the-lanesborough-grill-r597933). City pages are paginated automatically (25 restaurants per page).

## `scrapeDetails` (type: `boolean`):

Enrich each restaurant and push it once as a full detail row (description, chef name, phone, menus with sections and items, review texts, TripAdvisor ratings, bookable time slots, photo gallery) over the same proxy-free API. When disabled, each restaurant is pushed as a lighter search row instead. maxItems caps the number of restaurant rows either way.

## `scrapeReviews` (type: `boolean`):

Also store each review as its own row in the separate 'reviews' dataset (run's Storage tab). Review texts are embedded in the detail rows either way; toggle this on only when you want all reviews as individual rows. Implies scrapeDetails. Each review then counts as a pay-per-event charge.

## `maxReviewsPerRestaurant` (type: `integer`):

How many reviews to fetch per restaurant, applied whenever details are scraped (embedded in the detail rows and, when scrapeReviews is on, in the separate reviews dataset). The GraphQL API returns up to 25 reviews per page and is paginated automatically.

## `maxItems` (type: `integer`):

Hard cap on the number of restaurant rows for the whole run.

## `maxItemsPerSearch` (type: `integer`):

Cap on how many restaurants are collected from a single city/search URL (the API returns up to 25 per page). Everything - search and detail - runs proxy-free on TheFork's mobile API.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.thefork.com/restaurants/london-c665790"
    }
  ],
  "scrapeDetails": false,
  "scrapeReviews": false,
  "maxReviewsPerRestaurant": 50,
  "maxItems": 100,
  "maxItemsPerSearch": 200
}
```

# Actor output Schema

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

No description

## `reviews` (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 = {
    "startUrls": [
        {
            "url": "https://www.thefork.com/restaurants/london-c665790"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/thefork-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 = { "startUrls": [{ "url": "https://www.thefork.com/restaurants/london-c665790" }] }

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/thefork-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 '{
  "startUrls": [
    {
      "url": "https://www.thefork.com/restaurants/london-c665790"
    }
  ]
}' |
apify call ahmed_jasarevic/thefork-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ahmed_jasarevic/thefork-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/2hdZt9KX0ayowHODw/builds/CVDazcyKTaAvabUqm/openapi.json
