OpenTable Reviews & Restaurants Scraper, No Login avatar

OpenTable Reviews & Restaurants Scraper, No Login

Pricing

from $0.68 / 1,000 reviews

Go to Apify Store
OpenTable Reviews & Restaurants Scraper, No Login

OpenTable Reviews & Restaurants Scraper, No Login

Get OpenTable guest reviews with overall, food, service, ambience and value ratings, dined date and restaurant replies, or search restaurants by city with cuisine, price band, rating, review count, address and phone. No login.

Pricing

from $0.68 / 1,000 reviews

Rating

0.0

(0)

Developer

Cliqto Media

Cliqto Media

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Categories

Share

Paste OpenTable restaurant links and get their guest reviews with overall, food, service, ambience and value ratings, the dined date and the restaurant's reply, or search OpenTable restaurants by city and get cuisine, price band, rating, review count, address and phone. No login, cookies or API key.

Use it to track what diners say about your restaurant or your competitors, or to build a restaurant list for a city. The smallest run is one restaurant link with 20 reviews: it takes about 20 seconds and costs about $0.041.

OpenTable Reviews & Restaurants Scraper: restaurant links or a city in, reviews with food, service and ambience ratings or restaurant rows out

Table of contents

What it does

The Actor reads public pages of OpenTable, the restaurant booking site. It has two modes:

  • Reviews — you add restaurant links or IDs. For each restaurant you get one restaurant row with its details, then its reviews, newest first (or highest / lowest rated first).
  • Search — you add a city or area. You get the restaurants OpenTable lists there, one row per restaurant, with details from each restaurant page.

All rows go to one Dataset with two views: Reviews and Restaurants. A view chooses the columns; it does not filter rows, so filter by type (review or restaurant) when you export. A run summary goes to the Key-value store as RUN_SUMMARY.

This Actor is not made by OpenTable and is not connected to OpenTable. It reads only what OpenTable shows to every visitor without login.

Good fit

  • Restaurant owners and marketing teams who watch their own and competitors' OpenTable reviews, ratings and replies.
  • Analysts who compare restaurants in a city by cuisine, price band, rating and review count.
  • Scheduled monitoring: with reviewsSince a run reads only new reviews and stops at the first older one.

How it works

  1. The Actor reads OpenTable's public pages and its reviews feed over plain HTTPS, the same data any visitor sees without login. No browser starts while OpenTable lets these requests in, so runs are fast.
  2. In Reviews mode it opens each restaurant page, saves the restaurant row, then reads its reviews page by page until your limits or your reviewsSince date. In Search mode it reads OpenTable's restaurant list for your location and, if details are on, opens each restaurant page.
  3. If OpenTable refuses these requests, at the start or later in the run, the Actor tries a fresh session, then US residential addresses, and then a real Chrome browser for the rest of the run. Plain HTTP gets up to 4 residential sessions; Chrome then gets one more residential address and 30 seconds for its first answer, so a run refused everywhere stops in about a minute and a half. This is included in the price. A server error at OpenTable (HTTP 5xx) is retried 3 times and then stops the run; it does not switch routes.
  4. It saves review and restaurant rows to the Dataset, with status on each restaurant row, and a run summary as RUN_SUMMARY. Its route field says how OpenTable was read: http (no browser) or browser (Chrome was needed).

Quick start

  1. Open the Input tab.
  2. Keep What to scrape (mode) as Reviews of restaurant URLs.
  3. In Restaurant URLs or IDs (restaurantUrls) keep the example link or paste your own, e.g. https://www.opentable.com/r/brooklyn-chop-house-new-york.
  4. Keep Max reviews per restaurant (maxReviewsPerRestaurant) at the prefilled 20.
  5. Click Start.
  6. Open the Output tab, view Reviews, and check rating, text and dinedAt.

Expected result: one restaurant row and 20 review rows, in about 20 seconds.

Use cases

Buyer jobInput pathOutput entityKey fieldsNext integration
Read guest feedback for a restaurantrestaurantUrls, maxReviewsPerRestaurantreviewrating, ratingFood, ratingService, text, dinedAtExport CSV or Excel
Check how a restaurant answers reviewsrestaurantUrls, sortReviewsBy: "lowest"reviewrating, restaurantReply, restaurantReplyAtSpreadsheet or BI tool
Get new reviews every weekrestaurantUrls, reviewsSince: "7 days"reviewreviewId, submittedAt, rating, textApify schedule + API
Build a restaurant list for a citymode: "search", locationrestaurantname, cuisine, priceBand, rating, reviewCount, phoneCRM or map

Input

Input fields

FieldPlain nameTypeRequiredDefault / prefillAllowed valuesEffectExampleRecommendation
modeWhat to scrapestringnodefault reviews, prefill reviewsreviews, searchReviews of the links below, or restaurants for a location"search"If you fill only location, the Actor switches to Search; if only links, to Reviews
restaurantUrlsRestaurant URLs or IDsarray of stringsin Reviews modeprefill: 1 New York linkup to 200; /r/<name> links, /restaurant/profile/<id> links, links with ?rid=, numeric IDs, any OpenTable country siteWhich restaurants to read["https://www.opentable.com/r/brooklyn-chop-house-new-york", "1017331"]One run reads the first 40; the rest are listed as not_started (free). Duplicates are read once
locationLocationstringin Search modenoneup to 200 charactersCity, neighborhood or area to search"Chicago"Use the name you would type on OpenTable
maxReviewsPerRestaurantMax reviews per restaurantintegernodefault 100, prefill 201–10,000Most reviews for each restaurant500Each returned review is one paid event
maxItemsMax resultsintegernoempty: 1,000 reviews (Reviews) or 30 restaurants (Search)Reviews 1–50,000; Search 1–1,000Most rows in the whole run30In Search with details, keep it at 38 or less for details on every row
sortReviewsByReview orderstringnonewestnewest, highest, lowestWhich reviews come first"lowest"Use lowest to find complaints
reviewsSinceOnly reviews sincestringnononea date like 2026-01-31, an ISO time, or 30 days, 2 weeks, 6 months, 1 yearOnly reviews submitted on or after this time"30 days"With newest order the run stops at the first older review, so you pay only for new ones
includeRestaurantDetailsInclude restaurant detailsbooleannotruetrue, falseSearch only: open each restaurant page for address, phone, hours and sub-ratingsfalseTurn off for a faster list with name, cuisine, price band, rating and review count

Empty input: the Console fills in the prefill. Through the API, an input with no links and no location fails with a clear invalid_input message; only the start is charged.

Interacting settings

WhenInput AInput BEffective behaviorExampleCost/result effect
Many restaurantsmaxReviewsPerRestaurantmaxItemsThe run stops at whichever limit comes first10 links × 500, maxItems 1,000At most 1,000 review events
MonitoringreviewsSincesortReviewsBy: "newest"Reading a restaurant stops at the first older review"7 days"No new reviews → only the start and restaurant rows
reviewsSince with another orderreviewsSincesortReviewsBy: "highest"Older reviews are skipped but still read"30 days" + highestSlower; you still pay only for returned reviews
Search with detailsincludeRestaurantDetails: truemaxItems above 38Rows past the page limit come with search-list data, status: "partial" and a warningmaxItems 60Same restaurant price per row
Both filledrestaurantUrlslocationmode decides which one is usedmode: "search"The other field is ignored

Input examples

Reviews of one restaurant (prefill)

{
"mode": "reviews",
"restaurantUrls": ["https://www.opentable.com/r/brooklyn-chop-house-new-york"],
"maxReviewsPerRestaurant": 20
}

Expected behavior: the Actor opens the restaurant page and reads its 20 newest reviews. Expected output: 1 restaurant row and 20 review rows with rating, text, dinedAt, restaurantReply. Limit or cost note: about 20 seconds and about $0.041 (start $0.022 + restaurant $0.003 + 20 × $0.0008).

Restaurants in a city

{
"mode": "search",
"location": "Chicago",
"maxItems": 30
}

Expected behavior: the Actor reads OpenTable's restaurant list for Chicago and opens each restaurant page. Expected output: 30 restaurant rows with name, cuisine, priceBand, rating, phone. Limit or cost note: about 40 seconds and about $0.11 (start $0.022 + 30 × $0.003).

Output

Output fields

Review rows (type: "review"):

FieldMeaningTypeCan be empty?Example / enumSource / notes
typeRow typestringnoreview—
restaurantId, restaurantName, restaurantUrlThe restaurant this review is aboutinteger / stringno1017331—
reviewIdOpenTable review IDstringrarelyOT-1017331-261886-120047159362Use it to remove duplicates between runs
ratingOverall rating 1–5numberyes, if the diner gave none5—
ratingFood, ratingService, ratingAmbience, ratingValueSub-ratings 1–5numberyes4null = not rated, not 0
noiseThe diner's noise answerstringyesQUIET, MODERATE, ENERGETIC, DO_NOT_RECALL—
textReview textstringyes"loved the ambiance…"HTML entities decoded, line breaks kept
dinedAtWhen the diner ate therestringyes2026-09-30T18:30:00-04:00Restaurant local time with offset
submittedAtWhen the review was submittedstringyes2026-10-01T21:53:34ZUTC
reviewerName, reviewerMetro, reviewerReviewCount, reviewerIsVipPublic reviewer profilestring / integer / booleanyesDiner1, Chicago, 8, falsePublic display name only
restaurantReply, restaurantReplyAtThe restaurant's public replystringyes, when there is no reply——
helpfulUp, helpfulDownHelpful votesintegeryes0—
verified, fromPreviousConceptVerified diner; written for an earlier conceptbooleanyestrue, false—
photoCountNumber of photosintegerno0Photos are not downloaded
source, fetchedAtAlways opentable; read time (UTC)stringno2026-10-14T15:29:52.739Z—

Restaurant rows (type: "restaurant"):

FieldMeaningTypeCan be empty?Example / enumSource / notes
statusRow resultstringnocomplete, partial, not_found, errorSee Output entities
restaurantId, name, urlRestaurant identityinteger / stringnull only on not_found / errorBrooklyn Chop House - Downtown—
cuisine, cuisinesMain cuisine; all cuisinesstring / arrayyesSteakhouse—
priceBand, priceLevel, currencySymbolPrice per personstring / integer / stringyes$31 to $50, 3, $—
rating, ratingFood, ratingService, ratingAmbience, ratingValueAverage ratings 1–5numberyes4.1Based on recent reviews, as on the OpenTable page
ratingNoise, ratingCount, ratingDistributionNoise 1–3; recent reviews counted; stars 1–5number / integer / objectyes{"1": 9, …, "5": 74}Details only
reviewCountAll-time written reviewsintegeryes3055—
address, street, city, state, postalCode, country, countryCodeAddressstringyes150 Nassau St, New York, NY 10038, United States—
neighborhood, metro, latitude, longitudeArea and positionstring / numberyesTriBeCa, 40.71—
phone, websiteContactsstringyes(212) 619-1200Details only
hours, diningStyle, dressCode, executiveChef, paymentOptionsRestaurant factsstring / arrayyesFine DiningDetails only
description, reviewSummary, awards, imageUrlText, OpenTable review summary, awards, photostring / arrayyes—Details only
permanentlyClosedOpenTable marks it as closedbooleanyesfalse—
detailsIncludedThe restaurant page was readbooleannotruefalse = search-list data only
searchLocation, searchPositionSearch mode: location and positionstring / integeryesChicago, 1null in Reviews mode
input, errorYour input entry; why the row is not completestringyesNot found on OpenTableSet on partial, not_found, error

null means OpenTable did not give the value. It never means 0.

Output entities and surfaces

SituationDataset/API/KVS/live viewResult shapeUser action
Normal itemDataset, views Reviews and RestaurantsOne restaurant row, then its review rows; or one restaurant row per search resultOpen, export or call the Dataset API
No reviews or no search resultsDataset + RUN_SUMMARYRestaurant row without reviews, or no rows; run SUCCEEDED with a warningCheck the link, reviewsSince or location
Restaurant not on OpenTableDatasetrestaurant row with status: "not_found", input, errorCheck the link
Link that is not OpenTableDatasetrestaurant row with status: "error" (free)Fix the link
Details skipped or restaurant page failed (Search)Datasetstatus: "partial", detailsIncluded: false, errorRun again with a smaller maxItems
More than 40 restaurants (Reviews)RUN_SUMMARYRun SUCCEEDED with status: "partial"; extra restaurants not_started (free), warningStart another run with the rest
OpenTable blocked, did not answer or kept answering HTTP 5xxRUN_SUMMARY, run statusRun FAILED with stopReason: "SOURCE_ERROR"; rows saved before the block stayTry again later
Max charge, timeout or abortRUN_SUMMARYRun SUCCEEDED, status: "partial", saved rows stayRaise the limit and run again

Output example

{
"type": "review",
"restaurantId": 1017331,
"restaurantName": "Brooklyn Chop House - Downtown",
"restaurantUrl": "https://www.opentable.com/r/brooklyn-chop-house-new-york",
"reviewId": "OT-1017331-261886-120047159362",
"rating": 5,
"ratingFood": 5,
"ratingService": 5,
"ratingAmbience": 4,
"ratingValue": 4,
"noise": "ENERGETIC",
"text": "loved the ambiance. Alex, our waiter, was FABULOUS! My filet was cooked to perfection…",
"dinedAt": "2026-09-30T18:30:00-04:00",
"submittedAt": "2026-10-01T21:53:34Z",
"reviewerName": "Diner1",
"reviewerMetro": "County Durham",
"reviewerReviewCount": 8,
"reviewerIsVip": false,
"helpfulUp": 0,
"helpfulDown": 0,
"restaurantReply": null,
"restaurantReplyAt": null,
"verified": true,
"fromPreviousConcept": false,
"photoCount": 0,
"source": "opentable",
"fetchedAt": "2026-10-14T15:29:52.739Z"
}

This is one full review row from the prefill run; the text is shortened and the reviewer name is replaced. restaurantReply: null means the restaurant did not reply. A field is null when OpenTable does not show it for this review.

Use case → fields

Buyer jobInput pathOutput entityKey fieldsNext integration
Watch guest feedbackrestaurantUrlsreviewrating, ratingFood, ratingService, text, dinedAtCSV or Excel export
Track replies to bad reviewsrestaurantUrls, sortReviewsBy: "lowest"reviewrating, restaurantReply, restaurantReplyAtSpreadsheet or BI tool
Collect only new reviewsrestaurantUrls, reviewsSincereviewreviewId, submittedAt, textApify schedule + Dataset API
Compare restaurants in a citymode: "search", locationrestaurantcuisine, priceBand, rating, reviewCount, phoneCRM or map

Pricing

Pricing unit

The Actor uses pay-per-event pricing. You pay for:

EventWhenPrice (free plan)Price (Gold plan and higher)
Actor startOnce per run, 2 events (the Actor always runs with 2 GB)$0.022 per run$0.022 per run
ReviewEach review saved$0.0008$0.00068
RestaurantEach restaurant row saved (search result, or the restaurant of the reviews you asked for)$0.003$0.0026
Restaurant not foundA link or ID that OpenTable does not have (not_found row)$0.0015$0.0015

Bronze and Silver plans pay prices between these. The start fee scales with run memory: $0.011 per GB, and the Actor always runs with 2 GB, so $0.022 per run. Platform usage (compute) and the residential address used when OpenTable refuses the Actor's own are included; you do not pay them separately.

Free: links that are not OpenTable (error rows) and restaurants left not_started. A partial restaurant row is charged as a normal restaurant row. A run with no results (no reviews since your date, or a city with no restaurants) costs only the start, $0.022. A failed run charges only the rows it saved before the failure, plus the start.

Cost examples

ScenarioInput scopeExpected item/event countBase chargeOptional chargeStop/cap behavior
Prefill1 link, 20 reviews1 restaurant + 20 reviews$0.022 start$0.003 + 20 × $0.0008 = $0.019about 20 s
One restaurant, 1,000 reviews1 link, maxReviewsPerRestaurant 1,0001 + 1,000$0.022$0.003 + $0.80
Weekly check, no new reviews1 link, reviewsSince: "7 days"1 restaurant$0.022$0.003stops at the first older review
City listlocation, maxItems 3030 restaurants$0.02230 × $0.003 = $0.09about 40 seconds
City with no resultslocation OpenTable does not know0$0.022noneSUCCEEDED with a warning

Set Maximum cost per run in the run options to cap your spend: the Actor stops before it goes over, keeps what it saved, and marks the run partial.

Limits

  • No reservations, table availability, menus or review photos (only photoCount).
  • Only public data. The Actor does not log in and does not return private diner data.
  • OpenTable shows at most 10,000 reviews of one restaurant in one order. For more, run again with another sortReviewsBy.
  • One run opens at most 40 OpenTable pages, because OpenTable blocks more. In Reviews mode that is 40 restaurants per run (reviews themselves do not count). In Search mode with details, about 38 restaurants get full details; the rest come with search-list data only.
  • Search returns at most 1,000 restaurants per run (the maxItems maximum). OpenTable may list fewer unique restaurants for a big city.
  • If OpenTable refuses every address the Actor tries in about a minute and a half, the run fails with a clear message; it does not return an empty result as success. Residential use per run is capped (after a plain-HTTP refusal, Chrome gets one residential address for about the first page); past the cap the run goes on from its own address and may stop early with the rows read so far.

API, export and integrations

  • API: start a run with POST https://api.apify.com/v2/acts/cliqtomedia~opentable-reviews-scraper/runs and read rows from the run's default Dataset (Apify API docs).
  • Export: download the Dataset as JSON, CSV, Excel or XML from the Output tab.
  • Scheduling: create an Apify schedule with reviewsSince (for example "7 days") to get only new reviews every week. Use reviewId to remove duplicates.

Use with AI agents (MCP)

  • MCP server URL with only this Actor: https://mcp.apify.com?tools=cliqtomedia/opentable-reviews-scraper (Apify MCP docs).

  • Smallest useful input:

    {"mode": "reviews", "restaurantUrls": ["https://www.opentable.com/r/brooklyn-chop-house-new-york"], "maxReviewsPerRestaurant": 20}
  • Key output fields: type (review or restaurant), rating (overall 1–5), text (review text), dinedAt (visit date), status (restaurant row result: complete, partial, not_found, error).

  • The prefill run takes about 20 seconds and costs about $0.041. Limits: up to 40 restaurants per run, up to 10,000 reviews per restaurant in one order, maxItems up to 1,000 in Search mode.

Troubleshooting

The run failed with "OpenTable could not be read"

Symptom: the run is FAILED and RUN_SUMMARY has stopReason: "SOURCE_ERROR". Likely reason: OpenTable refused every address the Actor tried in about a minute and a half, or did not answer in time. Check: open RUN_SUMMARY and see how many rows were saved before the failure. Action: start the run again a few minutes later. Rows saved before the failure stay in that run's Dataset.

Some restaurants are not_started

Symptom: the warning says some restaurants were not started. Likely reason: you added more than 40 restaurants. One run opens at most 40 OpenTable pages. Check: RUN_SUMMARY.restaurants lists every input with its status. Action: start another run with the restaurants that are not_started. They are free.

Search rows have no phone or address

Symptom: rows have status: "partial" and detailsIncluded: false. Likely reason: maxItems is above 38 with details on, or one restaurant page could not be read. Check: the row error field says which case it is. Action: run again with maxItems 38 or less, or search a smaller area.

A restaurant has fewer reviews than reviewCount

Symptom: reviewsSaved in RUN_SUMMARY is lower than reviewCount. Likely reason: reviewCount counts all written reviews ever; OpenTable shows at most 10,000 in one order, and reviewsSince or maxItems can stop earlier. Action: raise the limits or run again with another sortReviewsBy.

FAQ

Do I need an OpenTable account, cookies or a proxy?

No. The Actor reads public pages without login, cookies or API key. You do not set a proxy: if OpenTable refuses the Actor's own address, it switches to a US residential address by itself, at no extra charge.

Which OpenTable sites work?

Links from any OpenTable country site, for example opentable.com, opentable.co.uk or opentable.ca, and numeric restaurant IDs. Search works with the location names OpenTable knows.

Why does Search find fewer restaurants than OpenTable says?

OpenTable's list pages change and overlap while you read them. For big cities the Actor may get fewer unique restaurants than the total OpenTable shows; it says so in a warning. Search a smaller area for a fuller list.

How fresh is the data?

Every row is read live during the run; fetchedAt shows when. Ratings on restaurant rows are OpenTable's averages of recent reviews.

Support

For bugs, questions or feature requests, open an issue on the Issues tab of this Actor. Add the run ID, the input mode and the error text. Never send API tokens, passwords or account data.