# Resy Scraper - Restaurants, Ratings, Contacts & Reservations (`scrapesage/resy-scraper`) Actor

Scrape Resy restaurants by city, cuisine or URL: name, full address, phone, website, cuisine, price band, ratings, neighborhood, geo, restaurant group and live reservation availability. Turn dining venues into B2B leads. Export to JSON, CSV or Excel. Independent tool, not affiliated with Resy.

- **URL**: https://apify.com/scrapesage/resy-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** Lead generation, Travel, Agents
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.75 / 1,000 restaurant scrapeds

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

## Resy Scraper - Restaurants, Ratings, Contacts & Reservations

> **Disclaimer:** This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Resy or any of its subsidiaries. All trademarks mentioned are the property of their respective owners. "Resy" is referenced only to describe the publicly available website this Actor collects data from.

Extract **complete restaurant data from [Resy](https://resy.com)** - by city, by cuisine, or by URL. Get every venue's **name, full street address, phone, website, cuisine, price band, Resy rating, neighborhood, geo-coordinates, restaurant group** and optional **live reservation availability**. Every dining venue is a ready-to-use **B2B lead**: a contactable restaurant with phone, website, location and a quality score.

No login, no cookies, no browser - this actor reads Resy's own public data API directly, so the output is first-party and reliable.

### Why this Resy scraper?

This actor pulls the **full venue record from Resy's data API** and ships **a complete dataset** - including the contact fields that turn a listing into a lead:

| Data | This actor |
| --- | --- |
| Restaurant name, cuisine, price band | ✅ |
| Resy rating + number of ratings | ✅ |
| **Phone number** | ✅ |
| **Website + menu link** | ✅ when published |
| **Full street address + ZIP + cross streets** | ✅ |
| Neighborhood, city, state, country | ✅ |
| Latitude / longitude + timezone | ✅ |
| **Restaurant group / operator** (multi-location) | ✅ |
| Cross-platform IDs (Google, Foursquare) | ✅ when mapped |
| Editorial description & "why we like it" | ✅ when published |
| **Live reservation availability** (open slots) | ✅ opt-in |
| Lead score (0–100) per venue | ✅ |
| One clean dataset, no empty columns | ✅ |

### Use cases

- **Lead generation** - restaurants are active buyers of POS, reservation, marketing, delivery, payroll, supply and insurance products. Score them by quality and reach (`leadScore`, `phone`, `website`) and export straight to your CRM.
- **Restaurant-group prospecting** - `venueGroupName` and `venueGroupSize` surface multi-location operators, the highest-value accounts for B2B sales.
- **Market & competitive research** - map a city's dining scene by cuisine, price band, neighborhood and rating; benchmark venues and track new openings.
- **Reservation intelligence** - see which sought-after restaurants have open tables on a given date and party size.
- **Directory & app enrichment** - power restaurant guides, concierge tools and travel apps with standardized records, geo-coordinates and images.
- **Sales territory planning** - pull every Resy venue in a metro with full addresses and coordinates for route and territory planning.

### How to use

1. [Sign up for Apify](https://console.apify.com/sign-up) - the free plan is enough to try this actor.
2. Open the **Resy Scraper**, enter one or more **Cities** (e.g. `New York, NY`), or **Search terms** (e.g. `sushi`), and click **Start**.
3. Watch results stream into the dataset table.
4. **Export** as JSON, CSV, Excel, XML or RSS - or pull results programmatically via the [Apify API](https://docs.apify.com/api/v2).

### Input

```json
{
    "cities": ["New York, NY", "Los Angeles, CA"],
    "searchTerms": ["sushi", "steakhouse"],
    "maxResults": 200,
    "enrichVenueDetails": true,
    "includeAvailability": false,
    "priceBands": ["3", "4"],
    "minRating": 4,
    "monitorMode": false
}
```

- **cities** - cities to scrape every Resy restaurant in (`New York, NY`, `Austin, TX`, `Miami, FL`, …). Major Resy markets are resolved to a precise map search for full coverage; any other city falls back to a name search.
- **searchTerms** - free-text Resy searches: a cuisine (`sushi`, `steakhouse`), a neighborhood, or a specific restaurant name (`Le Bernardin`). Each term is searched separately.
- **venueUrls** - direct Resy venue URLs (`https://resy.com/cities/new-york-ny/venues/le-bernardin`).
- **maxResults** *(default 100)* - cap on restaurant records for the whole run.
- **enrichVenueDetails** *(default true)* - open each restaurant's Resy profile for the full record (street address, website, menu link, editorial description, restaurant group, timezone, Google/Foursquare IDs). One fast extra API call per restaurant.
- **includeAvailability** *(default false)* - also return bookable reservation slots for `reservationDate` and `partySize`. Note: when on, Resy returns only restaurants with open tables on that date.
- **reservationDate / partySize** - date (`YYYY-MM-DD`) and party size for availability checks.
- **priceBands / cuisineFilter / minRating** - keep only venues matching these filters.
- **monitorMode** *(default false)* - emit only restaurants not seen in previous runs (see below).

### Output

One record per restaurant (`type: "restaurant"`):

```json
{
    "type": "restaurant",
    "resyId": 834,
    "name": "Le Gratin",
    "profileUrl": "https://resy.com/cities/new-york-ny/venues/le-gratin",
    "address": "5 Beekman St",
    "neighborhood": "Lower Manhattan",
    "city": "New York",
    "region": "NY",
    "postalCode": "10038",
    "country": "United States",
    "latitude": 40.7116,
    "longitude": -74.0068,
    "timezone": "EST5EDT",
    "cuisines": ["French"],
    "primaryCuisine": "French",
    "priceRangeId": 2,
    "priceRange": "$$",
    "rating": 4.64,
    "ratingCount": 6972,
    "phone": "+12125979020",
    "website": "https://www.legratinnyc.com/",
    "venueGroupName": "Dinex",
    "venueGroupSize": 9,
    "isMultiLocationGroup": true,
    "googlePlaceId": "ChIJ...",
    "description": "Le Gratin is a French restaurant in the Lower Manhattan neighborhood of New York.",
    "imageUrl": "https://image.resy.com/...",
    "leadScore": 93,
    "searchLocation": "New York, NY",
    "scrapedAt": "2026-06-24T12:00:00.000Z"
}
```

With **includeAvailability** on, each record also carries `bookableSlots` (time + table type), `bookableSlotCount`, `availabilityDate` and `availabilityPartySize`.

Use the **Restaurants**, **Leads** and **Reservation availability** dataset views to switch between column sets.

#### What to expect (field coverage)

Verified across multiple cities, you can typically expect:

| Field | Coverage |
|---|---|
| name, city, region, neighborhood, cuisine, price band, rating, geo, profile URL | ~100% |
| **phone** | ~100% |
| **website**, full street address, ZIP, timezone, description | ~90–100% (with `enrichVenueDetails`) |
| restaurant group, Google place ID | usually present |
| menu link, Foursquare ID, editorial tagline / "why we like it", cross streets | present only when Resy publishes them |

A blank field means Resy doesn't publish that value for that venue - not that scraping failed. Nothing is dropped, so you always get the richest record available.

### Monitoring mode - only new restaurants

Turn on **monitorMode** to make the actor remember which restaurants it has already returned and emit **only restaurants not seen in previous runs** - perfect for tracking new restaurant openings in a market. It stores seen venue ids in a named key-value store (`monitorStoreName`, one per tracked market).

This **complements [Apify Schedules](https://docs.apify.com/platform/schedules)** and does not conflict with them: Schedules decide *when* the actor runs (e.g. every morning), and monitoring mode decides *what is new* in each run. Use both together to get a daily feed of just-opened restaurants in your target cities.

### How much does it cost to scrape Resy?

This Actor uses Apify's **pay-per-event** pricing: you are charged only for the results it delivers, with no monthly rental and no start fee. The events it can charge are:

- **Restaurant scraped** - One Resy restaurant: name, phone, cuisine, price band, rating, neighborhood, geo, images and search context.
- **Venue details enrichment** - Full profile add-on: street address, website, menu link, editorial description, restaurant group, timezone and cross-platform IDs. Charged only when enrichment succeeds.

The current price of each event is shown on the **Pricing** tab of this page. Set a maximum total charge on the run if you want a hard cap on spend, and use the input limits to control how much the Actor fetches.

### Automate & schedule

Run this actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** - start runs, fetch datasets, and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[apify-client for Python](https://docs.apify.com/api/client/python/)** - official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** - run it daily/weekly to monitor new restaurant openings in a city or to refresh ratings and contacts.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** - trigger downstream actions (CRM import, Slack alert, email sequence) the moment a run finishes.

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

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/resy-scraper').call({
    cities: ['New York, NY'],
    maxResults: 200,
    enrichVenueDetails: true,
});

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

### Integrate with any app

Connect the dataset to 5,000+ apps - no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** - multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** - push new restaurant leads straight into your CRM.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** - get notified when a monitored city adds new restaurants.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** - auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** - pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** - trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. Call this actor from Claude, ChatGPT, or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** - ask your assistant to "list every Resy restaurant in Austin with phone and website" and let it run the scraper for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready**: AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)**: an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp), with no account and no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)**: agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### More scrapers from scrapesage

Build a complete **local-business & restaurant lead-gen stack**:

- **[DoorDash Scraper](https://apify.com/scrapesage/doordash-scraper)** - restaurants, full menus and prices by city.
- **[UberEats Scraper](https://apify.com/scrapesage/ubereats-scraper)** - restaurants, menus and delivery data.
- **[Just Eat Scraper](https://apify.com/scrapesage/just-eat-scraper)** - restaurant listings and menus.
- **[Zomato Scraper](https://apify.com/scrapesage/zomato-scraper)** - restaurants, ratings and reviews.
- **[US Restaurant Inspection Scraper](https://apify.com/scrapesage/us-restaurant-inspection-scraper)** - health inspection scores for US restaurants.
- **[Google Maps Scraper](https://apify.com/scrapesage/google-maps-scraper)** - local businesses with phone, website and reviews.
- **[Eventbrite Scraper](https://apify.com/scrapesage/eventbrite-scraper)** - events plus organizer leads (prices, emails, socials).
- **[Website Contact Scraper](https://apify.com/scrapesage/website-contact-scraper)** - emails, phones and socials from any website.

### Tips

- **Whole-metro coverage**: put the city in `cities` (e.g. `Chicago, IL`) - major Resy markets use a precise map search that returns every venue, paginated to your `maxResults`.
- **Cuisine by city**: combine `cities` with `cuisineFilter`, or add cuisines to `searchTerms` for the most precise targeting.
- **Cost control**: turn off `enrichVenueDetails` for a fast, cheap pass with the search-feed record (name, phone, cuisine, price, rating, neighborhood, geo); turn it on to add website, full address, menu and group data.
- **Best leads first**: sort the dataset by `leadScore` to surface rated, contactable, premium and multi-location venues at the top.
- **Recurring monitoring**: combine [Schedules](https://docs.apify.com/platform/schedules) with `monitorMode` to capture only newly listed restaurants.

### FAQ

**How do I scrape every restaurant in a city?** Put the city in `cities` (e.g. `New York, NY`). Major Resy markets resolve to a precise map search for full coverage; other cities use a name search.

**Does it need a Resy account or API key?** No. This actor reads Resy's own public data API - the same data the Resy website shows - with no login, cookie or key.

**Where do the phone and website come from?** From the restaurant's own Resy profile. Phone is on nearly every venue; website is published by most. When a venue doesn't list one, the field is simply absent.

**Can I get individual customer reviews?** Resy exposes an aggregate rating (average + number of ratings), which this actor returns. Individual review text is not part of Resy's public venue data, so it is not included.

**Can I export to Google Sheets, CSV, or Excel?** Yes - one click in the dataset view, or automatically on every run via the [Google Drive integration](https://docs.apify.com/platform/integrations/drive).

**How do I monitor new restaurant openings?** Turn on `monitorMode` and create a [Schedule](https://docs.apify.com/platform/schedules); each run returns only restaurants not seen before. Add a [webhook](https://docs.apify.com/platform/integrations/webhooks) to push them into your CRM.

**Is scraping Resy legal?** This actor collects publicly available data only. You are responsible for using the data in compliance with applicable laws (e.g. GDPR/CCPA for personal data) and Resy's terms.

### Disclaimer

**This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Resy or any of its subsidiaries. All trademarks mentioned are the property of their respective owners.**

"Resy" and any related marks are the property of their respective owners and are used here only in a descriptive, nominative sense - to identify the publicly accessible website from which this Actor collects data. This Actor is not an official Resy product, is not authorised or certified by Resy, and does not distribute Resy software. It collects only publicly available information; you are responsible for ensuring your use of that data complies with applicable laws, regulations and the terms of the source website.

### Need help?

Open an issue on the actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome - this actor is actively maintained.

# Actor input Schema

## `cities` (type: `array`):

Cities to scrape every Resy restaurant in, e.g. "New York, NY", "Los Angeles, CA", "Austin, TX", "Chicago, IL", "Miami, FL". Major Resy markets are resolved to a precise map search for full coverage; any other city falls back to a name search. One per row.

## `searchTerms` (type: `array`):

Free-text Resy searches - a cuisine ("sushi", "steakhouse"), a neighborhood, or a specific restaurant name ("Le Bernardin"). Each term is searched separately. Combine with Cities for cuisine-by-city coverage. One per row.

## `venueUrls` (type: `array`):

Direct Resy restaurant URLs to scrape, e.g. https://resy.com/cities/new-york-ny/venues/le-bernardin . One per row.

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

Cap on restaurant records across the whole run.

## `enrichVenueDetails` (type: `boolean`):

Open each restaurant's Resy profile for the complete record: full street address, website, menu link, editorial description, restaurant group, timezone and cross-platform IDs (Google / Foursquare). One extra fast API call per restaurant. Off = the fast, cheap search-feed record (name, phone, cuisine, price, rating, neighborhood, geo, images).

## `includeAvailability` (type: `boolean`):

Also return bookable reservation slots for the date and party size below. Note: when on, Resy returns only restaurants with open tables on that date, so coverage narrows to bookable venues. Off = all restaurants regardless of availability.

## `reservationDate` (type: `string`):

Date to check availability for (used only when 'Include live reservation availability' is on). Defaults to two days from the run date.

## `partySize` (type: `integer`):

Party size for availability checks.

## `priceBands` (type: `array`):

Keep only restaurants in these price bands: 1 = $, 2 = $$, 3 = $$$, 4 = $$$$. Leave empty for all.

## `cuisineFilter` (type: `array`):

Keep only restaurants whose cuisine matches one of these (case-insensitive substring, e.g. "italian", "sushi"). Leave empty for all.

## `minRating` (type: `integer`):

Keep only restaurants with a Resy rating at or above this value (1–5). 0 = no filter.

## `deduplicate` (type: `boolean`):

Skip a restaurant already emitted earlier in the same run (common when scraping a city across several cuisines).

## `monitorMode` (type: `boolean`):

Remember which restaurants were already returned and emit ONLY restaurants not seen in previous runs. Pairs with Apify Schedules to track new restaurant openings in a market over time (it does not conflict with Schedules - Schedules decide when to run, this decides what is new).

## `monitorStoreName` (type: `string`):

Named key-value store that holds the 'already seen' venue ids for monitoring mode. Use a different name per tracked market to keep histories separate.

## `maxConcurrency` (type: `integer`):

Maximum parallel API requests. Lower it if you see transient blocks; raise it for speed.

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

Proxy settings. Resy's public data API is read over standard Apify Proxy with automatic IP rotation; the default works well. Blocked requests retry automatically on a fresh IP.

## `urlsFromFile` (type: `string`):

Paste a list of URLs (one per line), OR one link to a .txt/.csv file, Google Sheet or Google Drive file containing them. Lets you import many Start URLs at once instead of typing each. Google Sheet/Drive share links are handled automatically.

## Actor input object example

```json
{
  "cities": [
    "New York, NY"
  ],
  "maxResults": 100,
  "enrichVenueDetails": true,
  "includeAvailability": false,
  "reservationDate": "",
  "partySize": 2,
  "priceBands": [],
  "minRating": 0,
  "deduplicate": true,
  "monitorMode": false,
  "monitorStoreName": "resy-scraper-monitor",
  "maxConcurrency": 8,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "urlsFromFile": ""
}
```

# Actor output Schema

## `results` (type: `string`):

All scraped restaurant records in the default dataset. Switch between the Restaurants, Leads and Reservation availability views to focus the columns.

# 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 = {
    "cities": [
        "New York, NY"
    ],
    "urlsFromFile": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/resy-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 = {
    "cities": ["New York, NY"],
    "urlsFromFile": "",
}

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/resy-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 '{
  "cities": [
    "New York, NY"
  ],
  "urlsFromFile": ""
}' |
apify call scrapesage/resy-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapesage/resy-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/6UdRMh8hWRdO09eqV/builds/zRc1hfC1nJ4g2Nofd/openapi.json
