OpenTable Reviews Scraper | Restaurant Reviews and Ratings avatar

OpenTable Reviews Scraper | Restaurant Reviews and Ratings

Pricing

from $4.25 / 1,000 reviews

Go to Apify Store
OpenTable Reviews Scraper | Restaurant Reviews and Ratings

OpenTable Reviews Scraper | Restaurant Reviews and Ratings

OpenTable reviews scraper: 100 diner reviews in 3 seconds, 78 fields each. Get overall, food, service, ambience, value and noise ratings, review text, diner, visit date, owner reply and the restaurant profile. Start from a restaurant page, name or id, filter by stars and date. No login needed.

Pricing

from $4.25 / 1,000 reviews

Rating

0.0

(0)

Developer

SilentFlow

SilentFlow

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

10 hours ago

Last modified

Share

OpenTable Reviews Scraper | Diner Reviews, Ratings and Owner Replies (2026)

1 URL. 100 OpenTable reviews. 78 fields per review.

From SilentFlow. Creators of Pinterest Scraper (#1 for โ€œpinterest pins scraperโ€ in Apify Store search) and Leboncoin Scraper Ppe, with 240,000+ combined lifetime runs.

Every OpenTable diner review of the restaurants you care about, one row per review, from a restaurant page, a restaurant name or an OpenTable id. Our test run turned the OpenTable page of Bestia in Los Angeles into its 100 newest reviews in under 3 seconds, each with the overall, food, service, ambience, value and noise ratings, the text, the diner, the visit date, and the restaurant's address, cuisine, price range, rating breakdown and bookings of the day on the same row, with no OpenTable account.

Why choose this actor?

Scrolling an OpenTable reviews tab page after page? Copying restaurant links one by one before you can read a single review? Getting one giant row per restaurant that never opens as a review table?

  • A whole review and its restaurant in one flat row. Each row carries 85 top-level fields: the review and its six ratings, the diner (name, city, review count, VIP status), the visit and publish dates, photos, the owner's reply, and the restaurant's full profile (address, coordinates, cuisine, price range, hours, dress code, rating breakdown by star, recent review count, review summary, bookings of the day, phone, website). On our three test runs, 76 to 78 of them carried a value on at least half the rows, 78 on the default run. The example output of the most used OpenTable reviews scraper shows 71 keys, for a restaurant, with its reviews nested inside it.
  • Start from a restaurant name or an id, not only a link. Type Carbone New York or Hawksmoor London and the run finds the restaurants whose name and city hold every word: 150 one- and two-star reviews of Carbone and two Hawksmoor branches in 6 seconds in our test. Type the OpenTable ids of your restaurants (11335, 1024645) to schedule the same list every week: 36 reviews published in the last 30 days, in 5 seconds. Restaurant pages of any OpenTable country site work in the same form. The most used OpenTable reviews scraper takes restaurant addresses only.
  • Nothing to fill in before you press Start. No field is required: the form opens with Bestia's page already in place and returns 100 reviews as is. The most used OpenTable reviews scraper will not start until you fill its required start URLs.

Try OpenTable Reviews Scraper

Try your first 100 reviews

Paste this input in the JSON tab of the Input page and press Start. It reads the 100 newest reviews of Bestia, the Italian restaurant in the Arts District of Los Angeles.

{
"startUrls": [
{ "url": "https://www.opentable.com/r/bestia-los-angeles" }
],
"maxReviews": 100,
"maxRestaurants": 1,
"sortBy": "newest"
}

It runs on the Apify Free plan. Each review becomes one row of your dataset: open the Output tab to see the table, switch to the "Ratings and replies" view for the food, service, ambience, value and noise scores and the owner's reply, or to the "Restaurant profile" view for the restaurant each review is about, and export the rows as JSON, CSV or Excel.

How it works

Copy to your AI assistant

Paste this block into Claude, ChatGPT or Cursor to give it the full picture of this scraper:

You have access to the OpenTable Reviews Scraper on Apify: silentflow/opentable-reviews-scraper
It reads the public diner reviews of OpenTable restaurants, any country site, without an account,
and returns one row per review, with the restaurant's profile on the same row.
Input schema (no field is required; give at least one restaurant page, name or id):
- startUrls (array of {url}): OpenTable restaurant pages: https://www.opentable.com/r/bestia-los-angeles,
https://www.opentable.co.uk/hawksmoor-spitalfields, https://www.opentable.com/restaurant/profile/96412.
A search page (https://www.opentable.com/s?term=carbone&latitude=40.71&longitude=-74.01) is read as a name.
- keywords (array of strings): restaurant names, with the city to pick the right branch:
"Carbone New York", "Hawksmoor London". Each gives the restaurants whose name and city hold every word.
- restaurantIds (array of strings): OpenTable restaurant ids, the number in /restaurant/profile/{id}: "96412".
- maxReviews (integer, default 100, max 10000): reviews saved per restaurant.
- maxRestaurants (integer, default 1): restaurants taken per name, best match first.
- sortBy (string, default "newest"): newest | oldest | highest_rating | lowest_rating.
- reviewsStartDate (string, optional): keep reviews published on or after it, "2026-01-01" or "30 days".
- starRatings (array of strings, optional): any of "1", "2", "3", "4", "5" (overall rating).
Output per review (85 fields, null when OpenTable gives no value):
- id (string, stable review id), url (string, the review's own link on the restaurant's permanent profile page),
restaurantId (string), restaurantName (string)
- text (string), rating, foodRating, serviceRating, ambienceRating, valueRating (number, 1 to 5),
noiseRating (number, 1 to 4, higher is louder), isRecommended (boolean|null)
- helpfulCount, notHelpfulCount, photosCount (integer), photoUrls (array|null),
hasOwnerResponse (boolean), ownerResponse (string|null), ownerResponseDate (RFC 3339|null)
- authorName, authorLocation, authorInitials (string), authorReviewsCount, authorRatingsCount (integer),
authorIsVip (boolean), authorLoyaltyTier (string|null), authorAvatarUrl (string|null)
- dinedAt, publishedAt (RFC 3339, UTC)
- restaurantUrl, restaurantAddress, restaurantCity, restaurantState, restaurantPostalCode,
restaurantCountry, restaurantCountryCode (ISO), restaurantLatitude, restaurantLongitude (number),
restaurantNeighborhood, restaurantCrossStreet
- restaurantPhone, restaurantWebsite, restaurantMenuUrl, restaurantFacebookUrl
- restaurantPrimaryCuisine, restaurantCuisines (array), restaurantPriceRange (label), restaurantPriceLevel
(1 to 4), restaurantDiningStyle, restaurantDressCode, restaurantHours, restaurantDescription,
restaurantExecutiveChef, restaurantParking, restaurantPublicTransit, restaurantPaymentOptions,
restaurantAccessibility, restaurantFeatures, restaurantSeatingOptions (arrays),
restaurantOffersTakeout, restaurantHasPrivateDining, restaurantHasGenderNeutralRestroom (boolean),
restaurantMaxPartySize, restaurantMaxAdvanceBookingDays (integer), restaurantCurrency (ISO),
restaurantDomain (the OpenTable site, such as opentable.co.uk)
- restaurantRating, restaurantFoodRating, restaurantServiceRating, restaurantAmbienceRating,
restaurantValueRating (number), restaurantReviewsCount, restaurantRecentReviewsCount,
restaurantFiveStarCount ... restaurantOneStarCount, restaurantRecommendCount, restaurantPhotosCount,
restaurantBookingsToday (integer), restaurantReviewSummary (string), restaurantImageUrl (string)
- input (the line of the input that led to the restaurant), scrapedAt (RFC 3339)
Use apify-client for Python or JavaScript: client.actor("silentflow/opentable-reviews-scraper").call(run_input=...)

How to scrape OpenTable reviews

Three inputs, from the simplest to the most filtered. Each one runs as is.

Get the latest reviews of a restaurant from its page

Copy the address of the restaurant on OpenTable and paste it. The run saves the newest reviews first.

{
"startUrls": [
{ "url": "https://www.opentable.com/r/bestia-los-angeles" }
],
"maxReviews": 200
}

Read the reviews of a restaurant you know by name

No link at hand? Type the name and the city. The run searches OpenTable, keeps the restaurant whose name and city hold every word, and reads its reviews.

{
"keywords": ["Carbone New York"],
"maxReviews": 100,
"sortBy": "newest"
}

Pull the complaints of a whole group, worst first

Take two branches per name, keep the one- and two-star reviews and read them from the lowest rating up. In our test this input returned 150 reviews from Carbone and two London Hawksmoor branches in 6 seconds, 43 of them with the owner's reply.

{
"keywords": ["Carbone New York", "Hawksmoor London"],
"maxRestaurants": 2,
"maxReviews": 50,
"sortBy": "lowest_rating",
"starRatings": ["1", "2"]
}

Input parameters

ParameterTypeDefaultDescription
startUrlsarray of URLsprefilled with Bestia, Los AngelesOpenTable restaurant pages, any country site. See the formats below.
keywordsarray of stringsnoneRestaurant names, with the city to pick the right branch: Carbone New York, Hawksmoor London, Bestia.
restaurantIdsarray of stringsnoneOpenTable restaurant ids, the number in a /restaurant/profile/96412 address.
maxReviewsinteger100Reviews saved per restaurant. A restaurant with fewer reviews gives all of them. OpenTable shows up to 10,000 reviews per restaurant in each order.
maxRestaurantsinteger1Restaurants taken per name, best match first. No effect on pages and ids.
sortBystringnewestnewest, oldest, highest_rating or lowest_rating.
reviewsStartDatestringnoneKeep only the reviews published on or after this date: 2026-01-01, or an age such as 7 days, 2 weeks, 3 months.
starRatingsarray of stringsnoneKeep only these overall ratings: any of 1 to 5.

Accepted restaurant formats:

  • Restaurant page: https://www.opentable.com/r/bestia-los-angeles, with or without what follows ?
  • Short restaurant page: https://www.opentable.com/bestia, https://www.opentable.co.uk/hawksmoor-spitalfields
  • Profile page: https://www.opentable.com/restaurant/profile/96412, including its /reserve pages and old links carrying ?rid=96412
  • Search page: https://www.opentable.com/s?term=carbone&latitude=40.7128&longitude=-74.006, read as the name carbone searched from that place
  • Any OpenTable country site: opentable.co.uk, opentable.de, opentable.jp, opentable.com.mx and the others
  • A page address without its site, as other OpenTable tools take it: r/central-park-boathouse-new-york-2
  • A bare id in restaurantIds: 96412
  • A name in keywords: Smith & Wollensky New York, Hawksmoor Spitalfields, Bubba Gump New York

A name only gives a restaurant whose name and city hold every word you typed. When none does, the log says so and the run moves on: a namesake in another city is never taken in its place, so a restaurant that is not on OpenTable gives no row rather than someone else's reviews.

A line that is not an OpenTable restaurant (a city or cuisine page, another site) is skipped and named in the log; the rest of the input still runs. The same restaurant given twice (a page and its id, for instance) is read once, and a review is never saved twice.

What data can you extract from OpenTable?

Each row is one review, with 85 top-level fields grouped the way you read them. On our three test runs (Bestia; Carbone and two Hawksmoor branches; Hawksmoor Spitalfields and Bubba Gump New York), 76 to 78 of them carried a value on at least half the rows: how many depends on how much of its profile each restaurant filled in.

GroupFields
Identity (4)id (the review's id, stable), url (the review's own link, on the restaurant's permanent profile page on OpenTable), restaurantId, restaurantName
Review and ratings (8)text, rating (overall, 1 to 5), foodRating, serviceRating, ambienceRating, valueRating, noiseRating (1 to 4, higher is louder), isRecommended (the diner's "would recommend" answer, when given)
Votes, photos and reply (7)helpfulCount, notHelpfulCount, photosCount, photoUrls (full-size photo links), hasOwnerResponse, ownerResponse, ownerResponseDate
Diner (8)authorName (first name as shown), authorLocation (the diner's city), authorInitials, authorReviewsCount, authorRatingsCount, authorIsVip, authorLoyaltyTier, authorAvatarUrl
Time (2)dinedAt (the visit), publishedAt (the review), both RFC 3339 in UTC
Restaurant location (11)restaurantUrl, restaurantAddress, restaurantCity, restaurantState, restaurantPostalCode, restaurantCountry, restaurantCountryCode, restaurantLatitude, restaurantLongitude, restaurantNeighborhood, restaurantCrossStreet
Restaurant contact (4)restaurantPhone, restaurantWebsite, restaurantMenuUrl, restaurantFacebookUrl
Restaurant profile (22)restaurantPrimaryCuisine, restaurantCuisines, restaurantPriceRange (the label OpenTable prints, in local currency), restaurantPriceLevel (1 to 4), restaurantDiningStyle, restaurantDressCode, restaurantHours, restaurantDescription, restaurantExecutiveChef, restaurantParking, restaurantPublicTransit, restaurantPaymentOptions, restaurantAccessibility, restaurantFeatures, restaurantSeatingOptions, restaurantOffersTakeout, restaurantHasPrivateDining, restaurantHasGenderNeutralRestroom, restaurantMaxPartySize, restaurantMaxAdvanceBookingDays, restaurantCurrency, restaurantDomain
Restaurant ratings and activity (17)restaurantRating, restaurantFoodRating, restaurantServiceRating, restaurantAmbienceRating, restaurantValueRating, restaurantReviewsCount (all time), restaurantRecentReviewsCount (the recent reviews the rating is based on), restaurantFiveStarCount, restaurantFourStarCount, restaurantThreeStarCount, restaurantTwoStarCount, restaurantOneStarCount, restaurantRecommendCount, restaurantReviewSummary (OpenTable's summary of what diners say), restaurantPhotosCount, restaurantImageUrl, restaurantBookingsToday
Meta (2)input (the page, name or id of your input that led to this restaurant), scrapedAt

A value OpenTable does not give is null, never an empty string. Ratings and counts are numbers, not text. The restaurant fields are read once per restaurant and repeated on each of its reviews, so a CSV export can be filtered or pivoted by city, cuisine or price level without a second file.

Which fields stay empty depends on the restaurant and the diner. Owner replies only exist where the restaurant answers: none on Bestia's 100 newest reviews, 43 of 150 on the complaints run above. On Bestia's 100 newest reviews, 38 carry the diner's "would recommend" answer and 11 a photo. A restaurant that never filled in its chef, menu link or public transit leaves those columns empty, and a restaurant nobody reviewed yet has no rating at all rather than a rating of zero.

Output example

One row of our default run, as the dataset stores it:

{
"id": "OT-96412-2110729164-170058752587",
"url": "https://www.opentable.com/restaurant/profile/96412#review-OT-96412-2110729164-170058752587",
"restaurantId": "96412",
"restaurantName": "Bestia",
"text": "Excellent experience, awesome food and a great wine list. Highly recommended if you enjoy the wine and food experience and pairing, as the sommelier helped us with some unique pairings that we enjoyed.",
"rating": 5,
"foodRating": 5,
"serviceRating": 5,
"ambienceRating": 5,
"valueRating": 4,
"noiseRating": 3,
"isRecommended": true,
"helpfulCount": 0,
"notHelpfulCount": 0,
"photosCount": 0,
"photoUrls": null,
"hasOwnerResponse": false,
"ownerResponse": null,
"ownerResponseDate": null,
"authorName": "Scott",
"authorLocation": "New Orleans",
"authorInitials": "S",
"authorReviewsCount": 5,
"authorRatingsCount": 0,
"authorIsVip": true,
"authorLoyaltyTier": "GOLD",
"authorAvatarUrl": null,
"dinedAt": "2026-09-28T19:30:00Z",
"publishedAt": "2026-09-29T18:17:00Z",
"restaurantUrl": "https://www.opentable.com/bestia",
"restaurantAddress": "2121 E. 7th Place",
"restaurantCity": "Los Angeles",
"restaurantState": "CA",
"restaurantPostalCode": "90021",
"restaurantCountry": "United States",
"restaurantCountryCode": "US",
"restaurantLatitude": 34.0336766,
"restaurantLongitude": -118.2291954,
"restaurantNeighborhood": "Downtown",
"restaurantCrossStreet": "Santa Fe Avenue",
"restaurantPhone": "(213) 514-5724",
"restaurantWebsite": "http://bestiala.com/",
"restaurantMenuUrl": "http://bestiala.com/menu/",
"restaurantFacebookUrl": "http://www.facebook.com/BestiaDTLA",
"restaurantPrimaryCuisine": "Italian",
"restaurantCuisines": ["Italian"],
"restaurantPriceRange": "$31 to $50",
"restaurantPriceLevel": 3,
"restaurantDiningStyle": "Casual Dining",
"restaurantDressCode": "Casual Dress",
"restaurantHours": "Dinner\nDaily 5:00 pmโ€“11:00 pm",
"restaurantDescription": "A multi-regional Italian restaurant in the Arts District of downtown Los Angeles.",
"restaurantExecutiveChef": "Ori Menashe & Genevieve Gergis",
"restaurantParking": "Valet",
"restaurantPublicTransit": null,
"restaurantPaymentOptions": ["AMEX", "Discover", "Mastercard", "Visa"],
"restaurantAccessibility": ["Gender Neutral Restroom", "Wheelchair Access"],
"restaurantFeatures": ["RESERVATION", "DIRECT_MESSAGING", "DINER_AI"],
"restaurantSeatingOptions": ["default", "hightop", "counter"],
"restaurantOffersTakeout": true,
"restaurantHasPrivateDining": true,
"restaurantHasGenderNeutralRestroom": true,
"restaurantMaxPartySize": 8,
"restaurantMaxAdvanceBookingDays": 60,
"restaurantBookingsToday": 154,
"restaurantCurrency": "USD",
"restaurantRating": 4.7,
"restaurantFoodRating": 4.7,
"restaurantServiceRating": 4.7,
"restaurantAmbienceRating": 4.5,
"restaurantValueRating": 4.2,
"restaurantReviewsCount": 9191,
"restaurantRecentReviewsCount": 1016,
"restaurantFiveStarCount": 825,
"restaurantFourStarCount": 125,
"restaurantThreeStarCount": 45,
"restaurantTwoStarCount": 13,
"restaurantOneStarCount": 8,
"restaurantRecommendCount": 119,
"restaurantReviewSummary": "Bestia is a culinary gem that consistently delivers \"outstanding food and service.\" With an energetic atmosphere and a diverse menu featuring standout dishes like \"mushroom pizza\" and \"scallop crudo,\" it impresses diners from all over. Known for its \"exceptional wine list\" and attentive service, Bestia promises a memorable dining experience.",
"restaurantPhotosCount": 23,
"restaurantImageUrl": "https://resizer.otstatic.com/v4/photos/23933357-1?width=1280&height=1280",
"restaurantDomain": "opentable.com",
"input": "https://www.opentable.com/r/bestia-los-angeles",
"scrapedAt": "2026-10-03T18:32:13Z"
}

id and url never change and are unique to each review: use id to deduplicate between two runs. restaurantUrl is the address OpenTable shows diners, which a restaurant can rename; url and restaurantId stay the same. Photo and image links point to OpenTable's image server and keep working as long as the photo stays on the restaurant's page.

Advanced usage

Watch the new reviews of your restaurants every week

Schedule this input every Monday on the Apify Console. It keeps only the reviews published in the last 7 days, newest first, and stops reading as soon as the reviews get older, so a weekly run stays short.

{
"restaurantIds": ["11335", "102156", "1024645"],
"reviewsStartDate": "7 days",
"sortBy": "newest",
"maxReviews": 1000
}

Add a webhook on the run to post the new rows to Slack or to append them to a Google Sheet.

Compare every branch of a restaurant group

Type the group's name and raise maxRestaurants: each branch whose name holds every word is read, and restaurantName, restaurantNeighborhood and the four sub-ratings let you rank them in one pivot table.

{
"keywords": ["Hawksmoor"],
"maxRestaurants": 10,
"maxReviews": 200,
"sortBy": "newest"
}

Paste an OpenTable search page and the name is searched from the latitude and longitude it carries, which puts the branch of that city first. Here, Carbone near Manhattan.

{
"startUrls": [
{ "url": "https://www.opentable.com/s?term=carbone&latitude=40.7128&longitude=-74.006" }
],
"maxReviews": 100
}

Build the full rating history of a restaurant

Read the oldest reviews first to follow how a restaurant's scores moved since it opened on OpenTable. dinedAt gives the month of each visit for a time series of foodRating, serviceRating and valueRating.

{
"startUrls": [
{ "url": "https://www.opentable.com/restaurant/profile/96412" }
],
"sortBy": "oldest",
"maxReviews": 2000
}

Collect the five-star praise for your marketing

Keep only the five-star reviews of the last three months, newest first, ready to quote on a menu, a website or a pitch deck. The authorName and authorLocation columns credit each quote the way OpenTable shows it.

{
"keywords": ["Bestia Los Angeles"],
"starRatings": ["5"],
"sortBy": "newest",
"reviewsStartDate": "3 months",
"maxReviews": 300
}

FAQ

What is OpenTable? OpenTable is the restaurant reservation platform of the United States, also used by restaurants in the United Kingdom, Ireland, Canada, Mexico, Germany, Spain, France, Japan and more, each country on its own site (opentable.co.uk, opentable.de, opentable.jp). Diners review the restaurant after a booked visit, so each review carries the date of that visit.

What does this scraper return exactly? One row per diner review: the text, the overall rating and the food, service, ambience, value and noise ratings, the diner's first name, city, review count and VIP status, the visit and publish dates, photos, the owner's reply, and 54 fields about the restaurant itself, from its address and coordinates to its rating breakdown and the bookings of the day.

Do I need an OpenTable account? No. The scraper reads what any visitor sees on a restaurant page, without logging in. There is no account, no API key and nothing to connect.

Which inputs can I use? Three kinds, in any mix: restaurant pages of any OpenTable country site, restaurant names (add the city to pick the right branch), and OpenTable restaurant ids. A search page of the site is read as a name searched from the place it shows.

How many reviews can I get per restaurant? As many as you set in maxReviews. OpenTable shows up to 10,000 reviews of a restaurant in each order; for the rare restaurants with more, run once newest first and once oldest first. In our test, 100 reviews took under 3 seconds.

Can I filter by stars and by date? Yes, and the filters combine. starRatings: ["1", "2"] with sortBy: "lowest_rating" and reviewsStartDate: "30 days" gives the complaints of the last month, worst first. The date is the publish date of the review. OpenTable lists reviews by visit date, so newest first the run stops once the visits are older than your date: a review posted long after the visit can be left out (3 of 113 five-star reviews of the last three months in our test on Bestia). Use another order to read every review and keep the dated ones.

How fresh is the data? Each run reads OpenTable live, at the time of the run, with nothing cached: a review is in the next run as soon as OpenTable shows it on the restaurant's page. Our default run, in the evening of October 3, held a review published that same morning.

Why is a field empty on some rows? Because OpenTable does not have it for that review or that restaurant. Few diners add photos, many restaurants never reply, and a restaurant decides which profile details it fills in. An empty value is null, never invented.

Why did a restaurant return no review? Either it has none yet (common on the newer country sites: the Narisawa page on opentable.jp had none in our test), or your filters kept none. The run says which in its log and in its final status, and moves on to the next restaurant.

What do the noise ratings mean? Diners rate the noise level of their visit; the scraper returns it as noiseRating from 1 to 4, higher meaning louder. Restaurants known as lively, like Bestia, get mostly 3 and 4.

Can I scrape many restaurants in one run? Yes. Add as many pages, names and ids as you need; they are read one after the other and each review is saved once, even when two inputs point to the same restaurant.

More SilentFlow scrapers

๐Ÿ›’ E-commerce

๐Ÿ’ผ Jobs

๐Ÿ  Real estate

๐Ÿ“ฃ Social media

๐Ÿข Business data

โœˆ๏ธ Travel

๐ŸŽฏ Lead generation

๐Ÿ”Ž SEO

๐Ÿงฐ More tools

Support

Need something this scraper doesn't do yet? We ship features fast.

  • Feature requests go straight to our backlog
  • Enterprise needs? We do custom integrations and high-volume plans
  • Pricing questions? Check the Monetization tab on the actor page

Response time: usually under 24 hours.

This Actor extracts publicly available diner reviews and restaurant profiles from OpenTable. It does not bypass any login, paywall or CAPTCHA, and never uses an OpenTable account. Users are responsible for complying with OpenTable's terms of service and applicable data protection laws (GDPR, CCPA, and PIPL where relevant). Rows carry diners' first names, cities and photos, which can be personal data: handle them accordingly, keep only what you need, and honor removal requests. OpenTable is a trademark of OpenTable, Inc.; this Actor is not affiliated with or endorsed by OpenTable. The data returned is informational; verify accuracy for regulated use cases.

OpenTable Reviews Scraper by SilentFlow: OpenTable diner reviews from a page, a name or an id, ready for your spreadsheet.