# TheFork Restaurant Scraper - Pay Per Result (`mscraper/thefork-restaurant-scraper`) Actor

Scrape TheFork restaurants by city, area or coordinates: ratings, prices, addresses, cuisines, offers, photos and optional contact details and reviews. Pay per unique restaurant, with pagination and budget limits.

- **URL**: https://apify.com/mscraper/thefork-restaurant-scraper.md
- **Developed by:** [mscraper](https://apify.com/mscraper) (community)
- **Categories:** Travel
- **Stats:** 2 total users, 1 monthly users, 50.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 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

Find restaurants on TheFork by city, area, landmark or coordinates. Export names, addresses, restaurant URLs, cuisines, average prices, ratings, review counts, photos and offers as JSON, CSV or Excel.

This is the updated replacement for [TheFork Scraper](https://apify.com/mscraper/thefork-scraper). It uses the current TheFork search and charges per restaurant saved.

### Quick start

```json
{
  "location": "Paris, France",
  "maxResults": 100,
  "maxPages": 4,
  "startPage": 1,
  "includeExtendedInfo": false,
  "includeReviews": false
}
```

Click **Start**, then open the **Restaurants** output to view or download your results. Proxy and website verification are included; no external account or API key is needed.

### Pricing

| Apify plan | Price per 1,000 restaurants |
| --- | ---: |
| Free / Starter (Bronze) | $10.00 |
| Scale (Silver) | $9.00 |
| Business (Gold) and above | $8.00 |

A start event costs **$0.0001 per started GB of memory**, with a minimum of one event per run. One unique restaurant written to the default dataset is one billed result. Optional details and reviews are included in that restaurant's price. Empty searches have no restaurant charges; the start event still applies.

Set the run's maximum charge in Apify Console to control spending. The Actor stops when it reaches that budget, `maxResults`, `maxPages`, the end of pagination, an empty page, or a page containing only already-seen restaurants. If a run fails after saving results, those saved results remain available and billed.

### Input

| Field | Default | Description |
| --- | --- | --- |
| `location` | `Paris, France` | City and country, area or landmark. Uses the first matching location. |
| `latitude`, `longitude` | — | Coordinate pair; overrides `location`. Search area is determined by TheFork. |
| `cityId` | — | Advanced: TheFork city ID, e.g. `415144` for Paris. Overrides name and coordinates. |
| `maxResults` | `100` | Maximum unique restaurants, from 1 to 5,000. |
| `startPage` | `1` | First page to fetch, from 1 to 200. |
| `maxPages` | `4` | Maximum number of pages to fetch, from 1 to 200. Each page has up to 25 restaurants. |
| `includeExtendedInfo` | `false` | Add available description, opening hours, vacation dates, phone, chef and menu link. |
| `includeReviews` | `false` | Add up to 20 reviews returned by TheFork for each restaurant. Not a full review-history export. |

For city names that resolve to a known TheFork city, search covers that city. Landmarks and coordinates search the nearby area. The `SUMMARY` output shows the resolved location, reported total count, pages fetched and stopping reason.

### Output

Each dataset item is a restaurant, with fields such as:

```json
{
  "id": "restaurant-uuid",
  "name": "Example Restaurant",
  "url": "https://www.thefork.com/restaurant/example-restaurant-r123456",
  "cuisine": "French",
  "address": { "street": "10 Example Street", "zipCode": "75001", "locality": "Paris", "country": "France" },
  "geolocation": { "latitude": 48.86, "longitude": 2.34 },
  "averagePrice": 35,
  "currency": "EUR",
  "rating": 9.2,
  "reviewCount": 120,
  "offers": [],
  "page": 1
}
```

The example above illustrates the schema. Missing source fields may be `null`. Offers and bookability reflect the search response; this Actor does not check availability for a specific booking time.

### Pagination and limitations

Restaurant IDs are deduplicated within each run. Search rankings and totals can change between runs, so page offsets are not stable exports of a fixed snapshot. Starting a separate run can return restaurants seen in an earlier run.

TheFork may occasionally block a proxy session or change its API. The Actor makes a limited number of verification attempts and reports a failed run if valid data cannot be obtained. Start a new run after a temporary block. Resurrecting an existing run with saved results is disabled to prevent duplicate charges.

For support, open an issue from this Actor's **Issues** tab and include your run URL.

# Actor input Schema

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

City and country or a landmark, for example Paris, France or British Museum, London. Coordinates take precedence when both are supplied.

## `latitude` (type: `number`):

Use together with longitude.

## `longitude` (type: `number`):

Use together with latitude.

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

Stop after this many unique restaurants or when the run budget is reached.

## `startPage` (type: `integer`):

Each page contains up to 25 restaurants.

## `maxPages` (type: `integer`):

Maximum pages from the starting page. Stops earlier at the end of results.

## `includeExtendedInfo` (type: `boolean`):

Adds available description, opening hours, phone and other details. The price per restaurant is unchanged.

## `includeReviews` (type: `boolean`):

Adds up to 20 reviews per restaurant. The price per restaurant is unchanged.

## `cityId` (type: `integer`):

Advanced: search all restaurants in a known TheFork city, e.g. 415144 for Paris. Overrides the location and coordinates.

## Actor input object example

```json
{
  "location": "Paris, France",
  "maxResults": 100,
  "startPage": 1,
  "maxPages": 4,
  "includeExtendedInfo": false,
  "includeReviews": false
}
```

# Actor output Schema

## `restaurants` (type: `string`):

No description

## `summary` (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": "Paris, France"
};

// Run the Actor and wait for it to finish
const run = await client.actor("mscraper/thefork-restaurant-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": "Paris, France" }

# Run the Actor and wait for it to finish
run = client.actor("mscraper/thefork-restaurant-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": "Paris, France"
}' |
apify call mscraper/thefork-restaurant-scraper --silent --output-dataset

```

## MCP server setup

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