# OpenTable Restaurants Scraper (`parsebird/opentable-restaurants-scraper`) Actor

Extract OpenTable restaurant listings: cuisine, price, rating, address, phone, coordinates, photos, and delivery/private-dining info. Scrape by metro area, search filters, or a single restaurant URL.

- **URL**: https://apify.com/parsebird/opentable-restaurants-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

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

### OpenTable Restaurants Scraper

OpenTable Restaurants Scraper extracts restaurant listing data from [OpenTable](https://www.opentable.com) — cuisine, price, rating, address, phone, coordinates, and photos — for a metro area, a filtered search, or a single restaurant.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">
Pull cuisine, price band, rating, review count, address, phone, coordinates, photos, and takeout/private-dining/delivery-partner flags for every restaurant in a city, a filtered search, or a single OpenTable profile.
</td>
</tr></table>

<br>

<table>
<tr>
<td colspan="2" style="padding:10px 14px;background:#DA3743;border:none;border-radius:4px 4px 0 0">
<span style="color:#FFFFFF;font-size:14px;font-weight:700;letter-spacing:0.5px">ParseBird OpenTable Suite</span>
<span style="color:#FFD1D1;font-size:13px">&nbsp;&nbsp;&bull;&nbsp;&nbsp;Restaurant &amp; review data</span>
</td>
</tr>
<tr>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-radius:0 0 0 4px;border-right:none;border-top:none;vertical-align:top;width:50%;background:#FFFFFF">
<a href="https://apify.com/parsebird/opentable-reviews-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">OpenTable Reviews Scraper</a><br>
<span style="color:#78716C;font-size:11px">Ratings, review text &amp; reviewer profiles</span>
</td>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-radius:0 0 4px 0;border-top:none;vertical-align:top;width:50%;background:#FFECEC">
<a href="https://apify.com/parsebird/opentable-restaurants-scraper" style="color:#DA3743;text-decoration:none;font-weight:700;font-size:13px">OpenTable Restaurants Scraper</a><br>
<span style="color:#DA3743;font-size:11px;font-weight:600">You are here</span>
</td>
</tr>
</table>

##### Copy to your AI assistant

```
Use the Apify actor "parsebird/opentable-restaurants-scraper" via the ApifyClient to scrape OpenTable restaurant listings. Example: client.actor("parsebird/opentable-restaurants-scraper").call(run_input={"startUrls": [{"url": "https://www.opentable.com/metro/las-vegas-restaurants"}], "results_wanted": 50, "max_pages": 5}). Inputs: startUrls (array of {url}, an OpenTable metro/city page, a search results page like opentable.com/s?term=..., or a single restaurant profile URL — takes priority over the filter fields below), location (string, city/neighborhood/landmark/restaurant name, used only when startUrls is empty), date (YYYY-MM-DD, must be set with time), time (24-hour HH:MM, must be set with date), people (integer, party size 1-20), sort (enum: recommended/distance/rating/price/name/newest), results_wanted (integer, default 20, max restaurants across all Start URLs), max_pages (integer, default 3, max search-result pages per search URL, up to 50 restaurants per page — metro pages are always fetched once), proxyConfiguration (object, defaults to Apify's Unblocker proxy group, required — OpenTable blocks Datacenter and Residential proxies). Output fields per restaurant include restaurantId, name, url, cuisine, price, rating, reviewCount, recentReservationCount, address, phoneNumber, neighborhood, description, latitude, longitude, profileImage, galleryImages, hasTakeout, hasPrivateDining, deliveryPartners, awards, sourceUrl, sourceType, and scrapedAt. Full API spec: https://apify.com/parsebird/opentable-restaurants-scraper/api. Get an API token at https://console.apify.com/settings/integrations.
```

### What does OpenTable Restaurants Scraper do?

OpenTable Restaurants Scraper is a listing-extraction tool for **OpenTable**. Give it a metro/city page, a search URL, filter criteria, or a single restaurant profile, and it returns structured restaurant data — cuisine, price, rating, contact details, coordinates, and photos — ready for a spreadsheet, map, or lead list.

- 🏙️ Scrape a whole metro/city page, a filtered search, or a single restaurant profile in one run
- 🔎 Search by location, date, time, party size, and sort order without building a URL yourself
- 📄 Automatic pagination on search result pages (up to 50 restaurants per page)
- 📍 Full contact and location data: address, phone, latitude/longitude, and neighborhood
- 📸 Profile photo and gallery photo URLs
- 🍽️ Takeout, private-dining, and delivery-partner flags
- ⚙️ Runs on Apify's infrastructure with scheduling, API access, and integrations

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| startUrls | array of `{url}` | No | Las Vegas metro URL | OpenTable metro/city pages, search result pages, or a single restaurant profile URL. Takes priority over the filters below. |
| location | string | No | — | City, neighborhood, landmark, or restaurant search term. Only used when Start URLs is empty. |
| date | string | No | — | Reservation date (`YYYY-MM-DD`). Use with `time`. |
| time | string | No | — | Reservation time, 24-hour `HH:MM`. Use with `date`. |
| people | integer | No | — | Party size, 1 to 20. |
| sort | enum | No | `recommended` | `recommended`, `distance`, `rating`, `price`, `name`, or `newest`. |
| results\_wanted | integer | No | `20` | Maximum number of restaurant listings to collect in this run, across all Start URLs. |
| max\_pages | integer | No | `3` | Maximum search-result pages to fetch per search URL. Each page can hold up to 50 restaurants. |
| proxyConfiguration | object | No | Unblocker (US) | Proxy settings. OpenTable's Akamai bot protection blocks Datacenter and Residential proxies — Unblocker is required. |

#### Metro page collection

```json
{
  "startUrls": [{ "url": "https://www.opentable.com/metro/las-vegas-restaurants" }],
  "results_wanted": 50,
  "max_pages": 5
}
```

#### Multiple search URLs

```json
{
  "startUrls": [
    { "url": "https://www.opentable.com/s?metroId=10&term=Las%20Vegas" },
    { "url": "https://www.opentable.com/s?metroId=511&term=New%20York" }
  ],
  "results_wanted": 100,
  "max_pages": 3
}
```

#### Filter-based search

```json
{
  "location": "Las Vegas",
  "date": "2026-09-15",
  "time": "19:00",
  "people": 2,
  "sort": "rating",
  "results_wanted": 20,
  "max_pages": 3
}
```

#### Single restaurant profile

```json
{
  "startUrls": [{ "url": "https://www.opentable.com/r/tao-asian-bistro-las-vegas" }],
  "results_wanted": 1
}
```

### What data can you extract from OpenTable?

| Field | Description |
|-------|-------------|
| restaurantId, name, url | Identifiers and profile link |
| cuisine, price, rating, reviewCount, recentReservationCount | Category and popularity signals |
| address, phoneNumber, neighborhood, latitude, longitude | Contact and location |
| description, profileImage, galleryImages | Marketing content and photos |
| hasTakeout, hasPrivateDining, deliveryPartners, awards | Feature flags and recognitions |
| sourceUrl, sourceType, scrapedAt | Metadata for auditing and reconciling rows |

### Output example

```json
{
  "restaurantId": 5056,
  "name": "TAO Asian Bistro - Las Vegas",
  "url": "https://www.opentable.com/r/tao-asian-bistro-las-vegas",
  "price": "$50 and over",
  "cuisine": "Contemporary Asian",
  "neighborhood": "The Venetian and Palazzo",
  "rating": 4.6,
  "reviewCount": 13898,
  "recentReservationCount": 196,
  "description": "TAO Asian Bistro invites you into a world of bold Pan-Asian flavors and captivating ambiance.",
  "address": "3377 S. Las Vegas Blvd., Suite 2025, Las Vegas, NV, 89109",
  "phoneNumber": "+17023888338",
  "latitude": 36.1215,
  "longitude": -115.1726,
  "profileImage": "https://resizer.otstatic.com/v3/photos/29631200-1?width=320&height=180&webp=true",
  "hasTakeout": true,
  "hasPrivateDining": true,
  "sourceUrl": "https://www.opentable.com/metro/las-vegas-restaurants",
  "sourceType": "locationLanding",
  "scrapedAt": "2026-09-27T10:30:00.000Z"
}
```

Download results as **JSON, CSV, Excel, HTML, or XML** from the Apify Console, or pull them programmatically through the [Apify API](https://docs.apify.com/api/v2).

### How to scrape OpenTable restaurants

1. Open **OpenTable Restaurants Scraper** on the Apify Store and click **Try for free**.
2. Paste a metro/city URL, a search URL, or a restaurant profile URL into **Start URLs** — or leave it empty and fill in **Location**, **Date/Time**, **Party size**, and **Sort by** instead.
3. Set **Max restaurants** and **Max search pages**.
4. Click **Start** and wait for the run to finish.
5. Open the **Dataset** tab to view, filter, and export the scraped restaurants.

### How it works

1. For each Start URL, the Actor checks whether it's a restaurant profile, a search results page, or a metro/city page — or builds a search URL from Location/Date/Time/People/Sort when no URL is given.
2. Restaurant profile URLs are fetched once each, reading the full profile data OpenTable embeds in the page.
3. Search result pages paginate automatically (up to 50 restaurants per page) until `max_pages` or `results_wanted` is reached. Metro/city pages are fetched once, since they don't paginate.
4. When a run has more than one metro/search URL, restaurant collection round-robins across them so the budget is shared rather than spent entirely on the first URL.
5. Every restaurant is written as one dataset row, deduplicated by restaurant ID across the whole run.

### How much does it cost to scrape OpenTable restaurants?

OpenTable Restaurants Scraper uses **pay-per-event** pricing — you're charged only for restaurants actually saved to your dataset.

| Plan | Price per restaurant | Price per 1,000 |
|------|----------------------|------------------|
| Free | $0.00129 | **$1.29** |
| Bronze | $0.00119 | **$1.19** |
| Silver | $0.00109 | **$1.09** |
| Gold | $0.00099 | **$0.99** |

Collecting 500 restaurants on the Free plan costs about $0.65. Apify's [monthly platform usage credits](https://apify.com/pricing) apply to this Actor like any other.

### Using the API

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")

run = client.actor("parsebird/opentable-restaurants-scraper").call(run_input={
    "startUrls": [{"url": "https://www.opentable.com/metro/las-vegas-restaurants"}],
    "results_wanted": 100,
    "max_pages": 5,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["name"], item["cuisine"], item["rating"])
```

#### JavaScript

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

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });

const run = await client.actor('parsebird/opentable-restaurants-scraper').call({
    startUrls: [{ url: 'https://www.opentable.com/metro/las-vegas-restaurants' }],
    results_wanted: 100,
    max_pages: 5,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Schedule recurring runs to track new openings and rating changes week over week, or connect it to Zapier/Make through Apify's [integrations](https://apify.com/integrations).

### Is it legal to scrape OpenTable?

Scraping publicly available data — like restaurant listings shown on a public OpenTable page — is generally considered legal, and courts have repeatedly upheld this for public web pages. This Actor only collects listing data OpenTable already displays to any visitor; it never accesses private diner accounts or reservation details. You are responsible for how you use the collected data and for complying with OpenTable's terms of service and applicable law in your jurisdiction. See Apify's [blog post on the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) for more detail.

### Related Actors

- [OpenTable Reviews Scraper](https://apify.com/parsebird/opentable-reviews-scraper) — diner reviews, ratings, and restaurant replies from OpenTable
- [TheFork Scraper](https://apify.com/parsebird/thefork-scraper) — restaurant and review data from TheFork (formerly La Fourchette / El Tenedor)

### FAQ

**Why does the Actor need Unblocker proxies specifically?**
OpenTable's Akamai bot protection blocks Apify's Datacenter and Residential proxy groups outright. Unblocker is the only proxy group that reliably loads OpenTable pages, so it's the required default.

**Does `max_pages` do anything on a metro/city URL?**
No. Metro and city pages show a fixed, curated set of restaurants and don't paginate — the Actor fetches them once regardless of `max_pages`. `max_pages` only affects search result pages (`opentable.com/s?...`).

**Do `date`, `time`, and `people` filter which restaurants come back?**
They're passed through to OpenTable's search as reservation context, but the restaurant list itself is driven mainly by `location` and `sort`. This Actor returns restaurant listing data, not live table availability.

**What happens if I provide both Start URLs and Location?**
Start URLs take priority — Location, Date, Time, People, and Sort are only used when Start URLs is empty.

**Can I scrape just one restaurant?**
Yes. Pass its profile URL (e.g. `opentable.com/r/tao-asian-bistro-las-vegas`) as a Start URL with `results_wanted: 1`.

**Can I schedule recurring runs?**
Yes. Use Apify's [Scheduler](https://docs.apify.com/platform/schedules) to run this Actor daily, weekly, or at any interval.

**Does this Actor have an API?**
Yes — every Apify Actor is automatically available as an API. See the [API tab](https://apify.com/parsebird/opentable-restaurants-scraper/api) for the full spec, or use the Python/JavaScript examples above.

**Something not working?**
Report it on the Actor's **Issues** tab in Apify Console — OpenTable occasionally changes its site, and prompt reports help keep this Actor maintained.

# Changelog

This Actor's version history is a separate document: https://apify.com/parsebird/opentable-restaurants-scraper/changelog.md

# Actor input Schema

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

OpenTable metro/city pages (e.g. opentable.com/metro/las-vegas-restaurants), search result pages (opentable.com/s?...), or a single restaurant profile URL (opentable.com/r/<slug>). Takes priority over Location/Date/Time/People/Sort below.

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

City, neighborhood, landmark, or restaurant name to search for. Only used when Start URLs is empty.

## `date` (type: `string`):

Reservation date. Must be set together with Time.

## `time` (type: `string`):

Reservation time in 24-hour HH:MM format, e.g. 19:00. Must be set together with Date.

## `people` (type: `integer`):

Number of people, from 1 to 20.

## `sort` (type: `string`):

Result ordering for search filters.

## `results_wanted` (type: `integer`):

Maximum number of restaurant listings to collect in this run, across all Start URLs combined.

## `max_pages` (type: `integer`):

Maximum number of search result pages to fetch per search URL. Each page can hold up to 50 restaurants. Metro/city pages are always fetched once, since they don't paginate.

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

OpenTable is protected by Akamai bot detection. Datacenter and Residential proxies are blocked — this Actor needs Apify's Unblocker proxy group to load pages successfully.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.opentable.com/metro/las-vegas-restaurants"
    }
  ],
  "sort": "recommended",
  "results_wanted": 20,
  "max_pages": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `dataset` (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.opentable.com/metro/las-vegas-restaurants"
        }
    ],
    "results_wanted": 20,
    "max_pages": 3,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "UNBLOCKER"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/opentable-restaurants-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.opentable.com/metro/las-vegas-restaurants" }],
    "results_wanted": 20,
    "max_pages": 3,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["UNBLOCKER"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/opentable-restaurants-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.opentable.com/metro/las-vegas-restaurants"
    }
  ],
  "results_wanted": 20,
  "max_pages": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call parsebird/opentable-restaurants-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/opentable-restaurants-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/SxEfqsrGCnVqGOt6y/builds/fZjTho2EknanuvBcw/openapi.json
