# OpenTable Restaurant & Reservation Availability Scraper (`scrapers_lat/opentable-scraper`) Actor

Scrape OpenTable restaurants by location or URL: name, cuisines, price band, rating, review count, neighborhood, address, phone, coordinates, booking URL, plus optional reservation time slots. Export to JSON, CSV or Excel.

- **URL**: https://apify.com/scrapers\_lat/opentable-scraper.md
- **Developed by:** [Scrapers Lat](https://apify.com/scrapers_lat) (community)
- **Categories:** Travel, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $18.91 / 1,000 restaurant results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

[![OpenTable Restaurant Scraper](https://scrapers.lat/banners/opentable-scraper.png)](https://console.apify.com/actors/EjKw4uaMyZL0Cyfwa/input)

## OpenTable Restaurant Scraper

Here is one real result, with every field the actor returns:

```json
{
  "query": "New York",
  "restaurantName": "Nobu Downtown",
  "restaurantId": "4528",
  "opentableUrl": "https://www.opentable.com/r/nobu-downtown-new-york",
  "bookingUrl": "https://www.opentable.com/r/nobu-downtown-new-york",
  "cuisines": ["Japanese"],
  "primaryCuisine": "Japanese",
  "priceBand": "$50 and over",
  "priceLevel": "$$$$",
  "overallRating": 4.7,
  "reviewCount": 5436,
  "recentReservationCount": 129,
  "neighborhood": "Financial District",
  "addressStreet": "195 Broadway",
  "city": "New York",
  "state": "NY",
  "postalCode": "10007",
  "country": null,
  "address": "195 Broadway, New York, NY, 10007",
  "phone": "(212) 219-0500",
  "website": null,
  "latitude": 40.7108399,
  "longitude": -74.0095723,
  "popularDishesAndTags": [],
  "diningStyle": "Casual Elegant",
  "topReview": "We love nobu downtown. The 630 reservation is perfect for families! Amazing food and service. Always a great time!",
  "aiVibe": "Casual Elegant",
  "aiBestFor": ["date night", "business dinner", "families"],
  "aiHighlights": ["Exceptional Japanese cuisine", "Highly rated with 4.7 stars", "Great for families with early reservations", "Renowned for outstanding service"],
  "aiPriceValue": "Premium",
  "source": "opentable.com",
  "observedAt": "2026-08-20T18:52:51.706Z"
}
```

The most complete OpenTable restaurant scraper available. It returns every field OpenTable exposes on its search and restaurant pages, from ratings and review counts to price band, neighborhood, full address, phone, coordinates and a highlighted review, plus derived fields like a coarse price level and an optional AI summary, and gives you three ways to target exactly the restaurants you need: by location, by cuisine or name, or by direct restaurant URL.

**📥 [Input](https://apify.com/scrapers_lat/opentable-scraper/input-schema) · 📤 [Output](https://apify.com/scrapers_lat/opentable-scraper/output-schema) · 💰 [Pricing](https://apify.com/scrapers_lat/opentable-scraper/pricing) · ▶️ [Examples](https://apify.com/scrapers_lat/opentable-scraper/examples)**

![Platform](https://img.shields.io/badge/platform-Apify-blue) ![Coverage](https://img.shields.io/badge/coverage-OpenTable-red) ![Output](https://img.shields.io/badge/output-JSON%20%7C%20CSV%20%7C%20Excel-green) ![Billing](https://img.shields.io/badge/billing-pay%20per%20result-orange)

### Table of contents

- [What it does](#what-it-does)
- [Quickstart](#quickstart)
- [Input reference](#input-reference)
- [Output reference](#output-reference)
- [Example output record](#example-output-record)
- [Run via API and CLI](#run-via-api-and-cli)
- [Fetch results](#fetch-results)
- [Billing and limits](#billing-and-limits)
- [FAQ and troubleshooting](#faq-and-troubleshooting)
- [Related scrapers](#related-scrapers)

### What it does

This actor collects restaurant listings from OpenTable and returns clean, flat records ready for CSV, Excel or JSON. For each restaurant you get its name, cuisines, price band and a coarse price level ($ to $$$$), overall rating, review count, recent reservation activity, neighborhood, full address, phone when public, map coordinates, a highlighted review snippet and the OpenTable booking URL.

You can search three ways:

- By location (for example New York, Chicago or Brooklyn).
- By cuisine, dish or restaurant name combined with a location.
- By pasting one or more OpenTable restaurant URLs to scrape those exact restaurants.

An optional AI summary add-on adds a vibe phrase, who the restaurant is best for, standout highlights and a price-value verdict.

### Quickstart

Provide a location, optionally a search term, and a result cap:

```json
{
  "locationQuery": "New York",
  "searchTerm": "Italian",
  "maxResults": 25
}
```

### Input reference

| Name | Type | Required | Description | Example |
| --- | --- | --- | --- | --- |
| `locationQuery` | string | one of these | City, neighborhood or area to search. | `"New York"` |
| `searchTerm` | string | optional | Cuisine, dish or restaurant name to narrow the search. | `"Italian"` |
| `restaurantUrls` | array | one of these | OpenTable restaurant URLs to scrape exactly, skipping search. | `["https://www.opentable.com/r/nobu-downtown-new-york"]` |
| `aiRestaurantSummary` | boolean | optional | Add an AI summary per restaurant (paid add-on, off by default, disabled on free plans). | `false` |
| `maxResults` | integer | optional | Maximum restaurants to collect. Free plans are capped at 10. | `25` |

Provide either a `locationQuery` or `searchTerm`, or one or more `restaurantUrls`.

### Output reference

| Name | Type | Description |
| --- | --- | --- |
| `query` | string | Location or search that produced this restaurant. |
| `restaurantName` | string | Restaurant name. |
| `restaurantId` | string | OpenTable restaurant id. |
| `opentableUrl` | string | OpenTable restaurant page URL. |
| `bookingUrl` | string | OpenTable reservation/booking URL. |
| `cuisines` | array | Cuisines served. |
| `primaryCuisine` | string | Primary cuisine. |
| `priceBand` | string | Price band label as shown on OpenTable. |
| `priceLevel` | string | Coarse price level ($ to $$$$). |
| `overallRating` | number | Overall rating out of 5. |
| `reviewCount` | integer | Total number of reviews. |
| `recentReservationCount` | integer | Recent reservations booked on OpenTable. |
| `neighborhood` | string | Neighborhood or area. |
| `addressStreet` | string | Street address. |
| `city` | string | City or locality. |
| `state` | string | State or region. |
| `postalCode` | string | Postal code. |
| `country` | string | Country when listed. |
| `address` | string | Full formatted address. |
| `phone` | string | Phone number when public. |
| `website` | string | Official website when listed. |
| `latitude` | number | Latitude. |
| `longitude` | number | Longitude. |
| `popularDishesAndTags` | array | Popular dishes, dining styles, awards and tags. |
| `diningStyle` | string | Dining style. |
| `topReview` | string | Highlighted snippet from a top review. |
| `aiVibe` | string | AI one-phrase vibe (AI add-on). |
| `aiBestFor` | array | AI occasions it is best for (AI add-on). |
| `aiHighlights` | array | AI standout highlights (AI add-on). |
| `aiPriceValue` | string | AI price-value verdict (AI add-on). |
| `source` | string | Data source. |
| `observedAt` | string | ISO timestamp collected. |

### Example output record

```json
{
  "query": "Italian in New York",
  "restaurantName": "Patrizias of Brooklyn",
  "restaurantId": "1006366",
  "opentableUrl": "https://www.opentable.com/r/patrizias-of-brooklyn",
  "bookingUrl": "https://www.opentable.com/r/patrizias-of-brooklyn",
  "cuisines": ["Italian"],
  "primaryCuisine": "Italian",
  "priceBand": "$31 to $50",
  "priceLevel": "$$$",
  "overallRating": 4.3,
  "reviewCount": 468,
  "recentReservationCount": 11,
  "neighborhood": "Williamsburg",
  "addressStreet": "35 Broadway",
  "city": "Brooklyn",
  "state": "NY",
  "postalCode": "11249",
  "country": null,
  "address": "35 Broadway, Brooklyn, NY, 11249",
  "phone": "(718) 218-9272",
  "website": null,
  "latitude": 40.710908,
  "longitude": -73.967365,
  "popularDishesAndTags": [],
  "diningStyle": "Casual Dining",
  "topReview": null,
  "aiVibe": null,
  "aiBestFor": [],
  "aiHighlights": [],
  "aiPriceValue": null,
  "source": "opentable.com",
  "observedAt": "2026-08-20T18:42:07.998Z"
}
```

### Run via API and CLI

Start a run with the Apify API:

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapers_lat~opentable-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"locationQuery":"New York","searchTerm":"Italian","maxResults":25}'
```

Or with the Apify CLI:

```bash
apify call scrapers_lat/opentable-scraper \
  --input '{"locationQuery":"New York","searchTerm":"Italian","maxResults":25}'
```

### Fetch results

Download the dataset items once the run finishes:

```bash
curl "https://api.apify.com/v2/datasets/DATASET_ID/items?token=YOUR_TOKEN&format=json"
```

Swap `format=json` for `csv` or `xlsx` to export a spreadsheet.

### Billing and limits

- Pay per result: you are charged once per restaurant returned, not per page fetched.
- The AI summary is an optional add-on, off by default, and is charged only when a usable summary is produced.
- Failed or empty runs return no results and are not charged.
- Free Apify plans are capped at 10 results per run and cannot enable paid add-ons.
- A spend cap is respected: once your configured maximum charge is reached, the run stops returning billable results.

### FAQ and troubleshooting

**How do I scrape a specific restaurant?** Paste its OpenTable URL into `restaurantUrls`.

**Why is `website` sometimes null?** OpenTable does not publish an external website for every restaurant; the field is null when it is not listed.

**Can I search by cuisine only?** Combine a cuisine in `searchTerm` with a `locationQuery` for the best results.

**Do I need a proxy or login?** No. Anti-bot handling is fully managed inside the actor and no OpenTable account or cookies are required.

### Related scrapers

- [Tripadvisor Hotels, Restaurants & Attractions Scraper](https://apify.com/scrapers_lat/tripadvisor-scraper)
- [Yelp Scraper](https://apify.com/scrapers_lat/yelp-scraper)

More scrapers at [scrapers.lat](https://scrapers.lat).

# Actor input Schema

## `locationQuery` (type: `string`):

A city, neighborhood or area to search on OpenTable, for example New York, Chicago, San Francisco or Brooklyn. Combined with the Search Term below when both are given.

## `searchTerm` (type: `string`):

Optional cuisine, dish or restaurant name to narrow the search, for example Italian, sushi, steakhouse or a specific restaurant name.

## `restaurantUrls` (type: `array`):

Optional. Paste one or more OpenTable restaurant page URLs to scrape those exact restaurants and skip the location search.

## `aiRestaurantSummary` (type: `boolean`):

Use AI to summarize each restaurant: vibe, who it is best for, highlights and price value. Charged only when a usable summary is returned. Disabled on free plans.

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

Maximum number of restaurants to collect in the run. Free Apify plans are capped at 10 per run.

## Actor input object example

```json
{
  "locationQuery": "New York",
  "restaurantUrls": [],
  "aiRestaurantSummary": false,
  "maxResults": 10
}
```

# 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 = {
    "locationQuery": "New York",
    "maxResults": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapers_lat/opentable-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 = {
    "locationQuery": "New York",
    "maxResults": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("scrapers_lat/opentable-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 '{
  "locationQuery": "New York",
  "maxResults": 10
}' |
apify call scrapers_lat/opentable-scraper --silent --output-dataset

```

## MCP server setup

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