Resy Scraper at a glance
Resy Scraper is a ready-to-run Apify actor from abotapi for collecting web data. Its documented output includes kind, recordid, venueid, url and name, which you can export as JSON, CSV or Excel or read through the Apify API. It costs $2.00 per 1,000 results on the Apify Free plan and from $1.20 on paid plans, with smaller per-run or optional feature charges listed on Apify.
- Runs on
- Apify cloud: console, API, schedules and integrations
- Data type
- Web data
- Pricing
- $2.00 per 1,000 results (Free plan), from $1.20 on paid plans
- Output
- Documented below · JSON, CSV, Excel
- Inputs
- 23 options
Scrape Resy restaurants and live reservation availability by city or URL. Get bookable times by date and party size, plus ratings, cuisine, price, phone, website, photos, and coordinates. Includes availability monitoring, resume, and MCP export.
What Resy Scraper can do
- Live, honest availability. Every restaurant ships with its actual bookable times for your date, party size and optional earliest time, and a fully booked restaurant comes back as a real zero slot answer instead of being dropped.
- Two ways to read it. Walk a whole city's restaurant list page by page, or paste exact restaurant links and read just those.
- One read per page, not per restaurant. A city search costs one page read for every 20 restaurants; the full profile read is priced per restaurant, and it is optional in search mode (URL mode always reads it).
- Full profiles on demand. Turn on one setting to also pull each restaurant's street address, phone, website, menu link, awards and a two week availability calendar.
- About 2,100 cities. Mostly United States, plus Mexico, Spain, Italy and Canada, matched by slug, name, page link or coordinates.
- Built for monitoring. Incremental mode returns only new, updated, reappeared, and (on a complete scan) expired restaurants on repeat runs, and a resumed run never re-adds what you already collected.
Choose what to collect
These inputs let you configure Resy Scraper - Restaurants & Live Table Availability. Open the actor on Apify to enter your values and review the current options.
| Input | What it controls |
|---|---|
modestring · required | Search reads every restaurant in one or more cities. URL mode reads only the restaurants you name. |
citiesarray | Search mode: one or more cities. Accepts a city slug (new-york-ny), a city name (Chicago), a city page link, or a latitude,longitude pair. Around 2,100 cities are covered, mostly United States plus Mexico, Spain, Italy and Canada. |
querystring | Search mode: narrow a city to a restaurant name, a cuisine or a dish, for example Italian, omakase, or a restaurant name. Leave empty for the whole city. |
radiusMilesinteger | Search mode: how far from the city centre to look. Leave empty to use the radius the city itself is published with. |
orderBystring | Search mode: the order the city's restaurants are returned in. |
resyCreditEligibleOnlyboolean | Search mode: return only restaurants flagged as eligible for the platform's dining credit. |
venueUrlsarray | URL mode: restaurant links (https://resy.com/cities//venues/), a bare restaurant slug, or a city link (https://resy.com/cities/ or https://resy.com/cities//search?query=), which runs a city search. A date or seats in a restaurant link is ignored; use the Date and Party size fields. Multi-value supported. |
Show 16 more inputs
| Input | What it controls |
|---|---|
urlsarray | Alias for Restaurant links, accepted under the name other Apify actors use for URL mode. Each entry is a restaurant link or slug; entries are read in order. |
startUrlsarray | Alias for Restaurant links, accepted under the name other Apify actors use. Each entry is a link string or an object with a url key. |
datestring | The day to check tables for, as YYYY-MM-DD, or the words today or tomorrow. Empty means today. A date in the past is read as today. |
partySizeinteger | How many guests the table is for. Restaurants with no table for this many guests come back with no times, which is itself the answer. |
timeFilterstring | Only return tables around and after this time, as HH:MM in the restaurant's own local time, for example 19:30. Leave empty for the whole service. |
maxItemsinteger | Stop after this many restaurants (0 = no limit; the run then stops when the cities' lists are exhausted). |
fetchDetailsboolean | Off by default: city search already returns name, cuisine, price band, rating, phone, photos, coordinates and every bookable time. Turn on to also read each restaurant's full profile and its two week availability calendar. Each read adds one Restaurant profile event. |
resumeFromRunIdstring | Paste a previous run ID or dataset ID to continue a large pull without returning restaurants already collected there. |
incrementalModeboolean | Turn this on for recurring availability monitoring. The first run returns every matching restaurant as NEW. Later runs normally return only NEW, UPDATED and REAPPEARED restaurants. What is compared: every field of the row, including the day's slot times, slot count, seating types, rating, price range, cuisine and address. What is excluded: image links, the checkedAt read timestamp and, inside each slot, the booking token and slot config id, which rotate between reads without a real change. A table opening up or disappearing shows as UPDATED with slots in changedFields. Turn on Emit unchanged or Emit expired only when you also want those rows returned (and billed). State is kept separately for each city, filter and date setup; use State key to name or deliberately share a monitoring campaign. |
stateKeystring | Optional. Name this monitoring campaign to keep its state stable, or deliberately share state across differently configured runs. Leave empty to let the actor derive a key automatically from the search, filter and date settings. |
emitUnchangedboolean | Off by default. Turn on to also return restaurants whose availability has not changed since the last run, marked UNCHANGED. This returns, and bills, extra rows you already have. |
emitExpiredboolean | Off by default. Turn on to also return restaurants that were present in a previous run but are no longer found, marked EXPIRED. Only produced once a run has fully scanned the tracked search. |
ignoreFieldsForChangesarray | Optional. Field names that must NOT make a restaurant count as UPDATED, for example rating. Use a dotted name such as slots.time to ignore one sub-field inside every slot. The fields stay in your results; they are only left out of the comparison and out of changedFields. Image links, the checkedAt read timestamp and the per-slot booking token and slot config id are always left out already. |
mcpConnectorsarray | Optionally send results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize one under Apify, Settings, API & Integrations, then select it here. Notion gets a rich page-per-item export; other connectors get a best-effort write or digest. Leave empty to skip; never changes the dataset output. |
notionParentPageUrlstring | URL or id of the Notion page under which restaurant pages are created. Required to enable the Notion export; ignored by other connectors. |
maxNotifyListingsinteger | Cap on restaurants written to each connector per run. Does not affect the dataset. |
Fields in the output
The documented dataset includes the fields below. Availability can depend on the source page and selected mode.
kindkindrecordIdrecordIdvenueIdvenueIdurlurlnamenameurlSlugurlSlugcuisinecuisinepriceRangepriceRangepriceRangeSymbolpriceRangeSymbolratingratingratingCountratingCountavailabilityDateavailabilityDateShow 62 more fields
datedatecheckedAtcheckedAtpartySizepartySizeisAvailableisAvailableslotCountslotCountfirstSlotTimefirstSlotTimelastSlotTimelastSlotTimeseatingTypesseatingTypesslotsslotscitySlugcitySlugcityNamecityNameneighborhoodneighborhoodlocalitylocalityregionregioncountrycountrystreetAddressstreetAddresspostalCodepostalCodecrossStreetcrossStreetaddress2address2latitudelatitudelongitudelongitudephonephonewebsitewebsitemenuUrlmenuUrlimageUrlimageUrlimagesimageswhyWeLikeItwhyWeLikeItaboutaboutseoDescriptionseoDescriptionkeywordskeywordsannouncementannouncementlargePartyMessagelargePartyMessageaverageSpendaverageSpendaverageSpendAmountaverageSpendAmountlocationCodelocationCodetimeZonetimeZonereopenDatereopenDatefoursquareIdfoursquareIdcollectionscollectionsminPartySizeminPartySizemaxPartySizemaxPartySizecurrencyCodecurrencyCodecurrencySymbolcurrencySymbolisGlobalDiningAccessisGlobalDiningAccessisResyCreditEligibleisResyCreditEligibleisTockInventoryisTockInventoryresySelectresySelectgooglePlaceIdgooglePlaceIdvenueGroupNamevenueGroupNameawardsawardssocialLinkssocialLinkswaitlistAvailablewaitlistAvailablewaitlistLabelwaitlistLabelnotifyAvailablenotifyAvailabledistanceMilesdistanceMilesavailabilityCalendaravailabilityCalendarnextAvailableDatenextAvailableDatedetailLoadeddetailLoadedchangeTypechangeTypechangedFieldschangedFieldsfirstSeenAtfirstSeenAtlastSeenAtlastSeenAtExample output
An example from this actor’s documentation. Values are illustrative; this is not a fresh live result.
{
"kind": "venue",
"recordId": "87654",
"venueId": 87654,
"name": "Sample Bistro Alpha",
"url": "https://resy.com/cities/new-york-ny/venues/example-restaurant",
"urlSlug": "example-restaurant",
"citySlug": "new-york-ny",
"cityName": "New York",
"neighborhood": "Sample Neighborhood",
"locality": "New York",
"region": "NY",
"country": "US",
"streetAddress": "123 Sample Street",
"postalCode": "10001",
"crossStreet": "Sample Avenue",
"latitude": 40.7128,
"longitude": -74.006,
"cuisine": [
"Italian"
],
"priceRange": 2,
"priceRangeSymbol": "$$",
"rating": 4.3,
"ratingCount": 128,
"collections": [
"Staff Picks",
"Pasta Picks"
],
"awards": [
"Sample Award 2025"
],
"phone": "+1 212 555 0100",
"website": "https://example-restaurant.example.com",
"menuUrl": "https://example-restaurant.example.com/menu",
"images": [
"https://img.resy.com/sample/1.jpg"
],
"imageUrl": "https://img.resy.com/sample/1.jpg",
"minPartySize": 1,
"maxPartySize": 8,
"isResyCreditEligible": true,
"isGlobalDiningAccess": false,
"isTockInventory": false,
"distanceMiles": 0.4,
"detailLoaded": true,
"availabilityDate": "2026-12-31",
"partySize": 4,
"isAvailable": true,
"slotCount": 2,
"firstSlotTime": "18:00",
"lastSlotTime": "20:30",
"seatingTypes": [
"Bar",
"Dining Room"
],
"slots": [
{
"time": "18:00",
"startsAt": "2026-12-31T18:00:00",
"endsAt": "2026-12-31T19:30:00",
"seatingType": "Dining Room",
"bookingToken": "rgs://resy/sample/token1"
},
{
"time": "20:30",
"startsAt": "2026-12-31T20:30:00",
"endsAt": "2026-12-31T22:00:00",
"seatingType": "Bar",
"bookingToken": "rgs://resy/sample/token2"
}
],
"waitlistAvailable": false,
"notifyAvailable": true,
"availabilityCalendar": [
{
"date": "2026-12-31",
"reservation": "available",
"event": "none",
"walkIn": "none"
}
],
"nextAvailableDate": "2026-12-31"
}Ways to use this data
- Reservation hunting tools and bots: watch specific restaurants or whole neighborhoods for a table to open up at the time and party size you want.
- Dining recommendation and discovery apps: feed cuisine, price band, rating and live availability into your own restaurant finder.
- Hospitality and market research: track price bands, ratings, collections and awards across a city's dining scene.
- Group and event planners: check bookable times and seating types across a shortlist of restaurants for one date and party size in a single run.
- Availability alert services: schedule incremental runs and notify users the moment a watched restaurant's table shows up as NEW or UPDATED.
Before you run
Start with a small input and check the resulting records against your expected fields. Source content and actor options can change; the current Apify listing is the reference for availability and pricing.
Questions about this actor
What data does Resy Scraper return?
The documented output for Resy Scraper includes kind, recordid, venueid, url, name, urlslug, cuisine and pricerange. Availability of each field depends on the source page and the selected mode.
How much does Resy Scraper cost?
It costs $2.00 per 1,000 results on the Apify Free plan and from $1.20 on paid plans, with smaller per-run or optional feature charges listed on Apify. The Apify listing shows the current rate for every plan.
Can I get only new or changed availability on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new, updated and reappeared restaurants, and unchanged ones are not billed unless you turn that on too.
Why do two runs of the same search return different times?
Availability is live: which restaurants have tables at which times changes by the hour. A different slot list an hour later is the correct answer, not a bug. That is exactly what incremental mode is for.
Why did my run fail instead of returning an empty dataset?
If every request is refused, the run stops with a clear message so "no tables tonight" is never confused with "nothing could be read". Run it again in a few minutes. If only some restaurants or pages could be read, you still get what was found.
Why did an incremental run return far more rows than Max items?
EXPIRED rows (restaurants missing from a complete scan since the last run) are not counted against Max items, which only governs the new and updated side of a run. A monitoring scope that shrinks sharply between runs can emit a burst of EXPIRED rows. This only happens on a complete, uncapped, unresumed scan; turn off Emit expired if you don't want these rows.
