# Resy Restaurant Availability Scraper (`simple.actors/resy-availability`) Actor

Scrape Resy restaurants: search by name and city for the full venue record — address, phone, website, cuisine, price, ratings, photos, Google Place ID — plus every open table for a date and party size, or a calendar of when a booked-out place opens up. Unofficial.

- **URL**: https://apify.com/simple.actors/resy-availability.md
- **Developed by:** [Simple Actors](https://apify.com/simple.actors) (community)
- **Categories:** Travel, Developer tools, Lead generation
- **Stats:** 1 total users, 1 monthly users, 87.2% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 availability checkeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Resy Restaurant Availability Scraper

Scrape restaurant data from Resy. Search by name and city to get the **full
venue record** — address, coordinates, phone, website, cuisine, price tier,
ratings, photos, restaurant group, Google Place ID — then read **every open
table** for a date and party size, or a **day-by-day calendar** of when a
booked-out restaurant actually has something.

**$1.00 per 1,000 results**, with Apify platform usage included — no monthly
fee, and nothing to pay for a run that legitimately finds nothing. A result is
one restaurant, with every field below.

*Unofficial. Not affiliated with, endorsed by, or sponsored by Resy.*

### What you can do with it

- **Build a restaurant dataset** — cuisine, price tier, rating and rating count,
  neighborhood, coordinates, phone, website and photos for every venue matching
  a name or a city.
- **Find a table** on a specific date for a specific party size, with the exact
  seating times, seating areas, turn times and deposit rules.
- **Answer "when can I get in?"** — the booking calendar marks every day in a
  window as available, sold out or closed, so one run finds the openings at a
  restaurant that is booked for weeks.
- **Monitor availability** — run it daily per venue and date to track how far
  ahead tables disappear, or to catch a cancellation.
- **Enrich your own records** — every item carries the Google Place ID and the
  Resy venue ID, so your list lines up with Resy's without fuzzy name matching.
- **Map a restaurant group** — each item names its hospitality group and lists
  the Resy IDs of every sibling restaurant.

### Two ways in

**Search by name.** `query` plus `city` finds restaurants across Resy's 2,000+
markets — US, Mexico, Spain, Italy, Japan, Canada and more. Resy ranks matches
across the country with your city first, so `Carbone` in Miami returns the Miami
location, then New York, Dallas and Las Vegas. Set `radiusKm` to keep results
inside one city.

```json
{ "city": "Miami", "query": "Carbone", "maxItems": 5 }
```

**Read specific venues.** `startUrls` takes Resy venue URLs and reads each one
directly. When it is set, the search inputs are ignored.

```json
{ "startUrls": [{ "url": "https://resy.com/cities/new-york-ny/venues/carbone" }] }
```

Either way, add availability, the calendar, or both:

```json
{
  "city": "New York",
  "query": "pizza",
  "maxItems": 10,
  "includeAvailability": true,
  "date": "2026-08-22",
  "partySize": 2,
  "includeCalendar": true,
  "calendarDays": 30
}
```

### What you get

One dataset item per restaurant. A plain venue read carries **79 fields**;
switching on availability and the calendar adds 15 more for **94 in total**.
Those 15 are left out rather than set to null when you do not ask for them, so
`slots` or `calendar` being absent means you did not request that layer. Every
field is listed below, so you can tell before running it whether the data you
need is in here.

```json
{
  "id": 6194,
  "name": "Carbone",
  "canonicalUrl": "https://resy.com/cities/new-york-ny/venues/carbone",
  "address": "181 Thompson Street",
  "crossStreet": "Bleecker Street",
  "neighborhood": "Greenwich Village",
  "locality": "New York",
  "region": "NY",
  "postalCode": "10012",
  "country": "United States",
  "latitude": 40.7279891,
  "longitude": -74.0002311,
  "timeZone": "EST5EDT",
  "phone": "+12122543000",
  "website": "http://carbonenewyork.com/",
  "menuUrl": "https://carbonenewyork.com/?menu=dinner",
  "googlePlaceId": "ChIJmSvG_ZFZwokRTOFeiLXzkmA",
  "foursquareId": "504b2a9ee4b006c435a465d3",
  "cuisine": ["Italian"],
  "priceRange": 4,
  "averageSpend": "$150",
  "rating": 4.74814,
  "ratingCount": 33328,
  "minPartySize": 1,
  "maxPartySize": 14,
  "images": ["https://image.resy.com/3/003/2/6194/eb7e05…/jpg/640x360"],
  "about": "Carbone is Chef Mario Carbone's homage to the great Italian American restaurants…",
  "whyWeLikeIt": "Carbone puts on the ritz of times gone by…",
  "needToKnow": "Reservations can be made up to 30 days in advance… a deposit of $50 per person…",
  "collections": ["Top Rated", "Global Dining Access"],
  "venueGroup": "Major Food Group",
  "venueGroupVenueIds": [6249, 7457, 8656, 10389],
  "socialLinks": [{ "name": "instagram", "value": "majorfoodgroup" }],
  "isGlobalDiningAccess": true,
  "isResyCreditEligible": true,
  "scrapedAt": "2026-08-19T02:43:16.478Z"
}
```

With `includeAvailability`, each item also carries its open tables:

```json
{
  "availabilityDate": "2026-08-22",
  "partySize": 2,
  "slotCount": 24,
  "earliestSlot": "2026-08-22 16:00:00",
  "latestSlot": "2026-08-22 21:45:00",
  "slotTypes": ["Dining Room"],
  "slots": [
    {
      "startTime": "2026-08-22 16:00:00",
      "endTime": "2026-08-22 17:30:00",
      "type": "Dining Room",
      "turnTimeSeconds": 5400,
      "minSize": 1,
      "maxSize": 2,
      "quantity": 13,
      "isPaid": true,
      "cancellationFee": 10,
      "cancelCutOffTime": "15:00:00",
      "token": "rgs://resy/69262/3772090/2/2026-08-22/…"
    }
  ]
}
```

With `includeCalendar`, it carries the booking window:

```json
{
  "calendarStart": "2026-08-19",
  "calendarEnd": "2026-09-18",
  "calendarLastBookableDate": "2026-12-25",
  "availableDates": ["2026-08-21", "2026-09-02"],
  "availableDateCount": 2,
  "calendar": [
    { "date": "2026-08-19", "reservation": "sold-out", "event": "not available", "walkIn": "available" },
    { "date": "2026-08-21", "reservation": "available", "event": "not available", "walkIn": "available" }
  ]
}
```

Set `includeRaw` to attach Resy's untouched JSON under `raw` when you need a
detail that has no named field.

The dataset ships four views: **Venues** (one row per restaurant), **Open
tables** (one row per bookable seating), **Booking calendar** (one row per day
per restaurant) and **Contact & identifiers**.

#### Every field

**Identity and links**

| Field | What it is |
|---|---|
| `id` | Resy's internal numeric venue ID — the key every other Resy endpoint takes. |
| `name` | Restaurant name as Resy lists it. |
| `url` | Resy page for the venue. |
| `canonicalUrl` | Canonical Resy venue URL — stable, safe to use as a key. |
| `urlSlug` | The venue's slug in its Resy URL. |
| `deepLink` | Link that opens the venue in the Resy mobile app. |

**Where it is**

| Field | What it is |
|---|---|
| `address` | Street address. |
| `address2` | Second address line, when the venue publishes one. |
| `crossStreet` | Nearest cross street. |
| `crossStreet2` | Second cross street, when published. |
| `neighborhood` | Neighborhood Resy places the venue in. |
| `locality` | City the venue is in. |
| `region` | State or region code. |
| `postalCode` | ZIP or postal code. |
| `country` | Country name. |
| `countryCode` | ISO 3166 country code. |
| `latitude` | Venue latitude. |
| `longitude` | Venue longitude. |
| `timeZone` | Venue time zone. Slot times are local to it, with no offset attached. |
| `locationName` | The Resy market the venue belongs to. |
| `locationCode` | Resy's short code for that market. |
| `locationSlug` | Resy's URL slug for that market — the value the venue endpoint needs. |

**Matching it to your own records**

| Field | What it is |
|---|---|
| `googlePlaceId` | Google Place ID for the venue — the reliable way to match it against your own records. |
| `foursquareId` | Foursquare venue ID, when Resy has one. |
| `fbPixelId` | Facebook pixel the venue runs, when published. |

**Contact**

| Field | What it is |
|---|---|
| `phone` | Reservations phone number in E.164 form. |
| `website` | The restaurant's own site. |
| `menuUrl` | Link to the menu, when the venue publishes one. |

**Cuisine and price**

| Field | What it is |
|---|---|
| `type` | Resy's primary cuisine label. |
| `cuisine` | Every cuisine tag Resy applies. Falls back to the primary cuisine in URL mode. |
| `priceRange` | Resy's price tier, 1 (cheapest) to 4 (most expensive). |
| `averageSpend` | Typical spend per person, formatted by Resy. |
| `averageSpendAmount` | Typical spend per person as a number. |
| `currencyCode` | ISO currency code for the prices below. |
| `currencySymbol` | Symbol Resy shows for that currency. |

**Ratings**

| Field | What it is |
|---|---|
| `rating` | Resy diner rating out of ratingScale. |
| `ratingCount` | How many diner ratings that average is built on. |
| `ratingScale` | Top of the rating scale, normally 5. |
| `ratings` | Every rating Resy shows, including critics' scores on their own scales. |

**Party size**

| Field | What it is |
|---|---|
| `minPartySize` | Smallest party Resy will take online. |
| `maxPartySize` | Largest party Resy will take online at this venue. |
| `largePartyMessage` | What the venue says to do about parties over the online limit. |

**Photos**

| Field | What it is |
|---|---|
| `images` | Venue photos published by Resy, largest listing size. |
| `heroImage` | First image — the one Resy leads with. |
| `mapImage` | Pre-rendered static map of the venue's block. |

**What the venue and Resy say about it**

| Field | What it is |
|---|---|
| `about` | The venue's own description of itself. |
| `whyWeLikeIt` | Resy's editorial note on the restaurant. |
| `needToKnow` | House rules: deposits, dress code, cancellation policy. |
| `tagline` | Short editorial tagline, when set. |
| `fromTheVenue` | A note written by the restaurant, when set. |
| `metaDescription` | The description Resy puts in the page's meta tags. |
| `keywords` | Search keywords Resy tags the venue with. |
| `collections` | Resy editorial lists the venue appears on. |
| `awards` | Awards Resy records for the venue. |
| `announcementHeadline` | Headline of any banner the venue is running. |
| `announcementBody` | Body text of that banner. |
| `announcementLinks` | Links in the banner — gift cards, delivery, and the like. |

**Restaurant group and socials**

| Field | What it is |
|---|---|
| `venueGroup` | The hospitality group that operates the venue. |
| `venueGroupId` | Resy's ID for that group. |
| `venueGroupVenueIds` | Resy IDs of the group's other restaurants — feed them back in to map a whole group. |
| `socialLinks` | The venue's social accounts. |

**Programmes, policies and booking rules**

| Field | What it is |
|---|---|
| `isActive` | Whether the venue is currently live on Resy. |
| `isGlobalDiningAccess` | Whether Amex Global Dining Access tables exist here. |
| `isGlobalDiningAccessOnly` | Whether every table is reserved for Global Dining Access cardholders. |
| `isResySelect` | Whether the venue is in Resy's Select programme. |
| `isResyCreditEligible` | Whether Amex dining credits apply here. |
| `isTockInventory` | Whether the tables come from Tock rather than Resy. Search mode only. |
| `inventoryTypeId` | Resy's inventory type for the venue. |
| `waitlistAvailable` | Whether Resy is running a waitlist for this venue. Only Resy's availability endpoint reports it, so this is answered truthfully in availability mode and false elsewhere. |
| `requiresReservationTransfers` | Whether the venue requires reservation transfers. |
| `allowMultipleReservations` | Whether one guest may hold several bookings. |
| `allowBypassPaymentMethod` | Whether a card on file can be skipped. |
| `enableResyPay` | Whether the venue takes payment through Resy. |
| `hospitalityIncluded` | Whether gratuity is included. |
| `taxIncluded` | Whether quoted prices include tax. |
| `hasExperiences` | Whether the venue sells ticketed experiences. |
| `transactionProcessor` | Processor the venue books through. |
| `reopenDate` | Date Resy records the venue as (re)opening. |

**Open tables — with `includeAvailability`**

| Field | What it is |
|---|---|
| `availabilityDate` | The date the slots below were read for. Availability mode only. |
| `partySize` | The party size the slots were read for. Availability mode only. |
| `slotCount` | Number of bookable tables found. Availability mode only. |
| `slots` | Every bookable table for the requested date and party size. Availability mode only; a venue with none is left out unless Keep unavailable venues is on. |
| `earliestSlot` | First bookable seating time that day. |
| `latestSlot` | Last bookable seating time that day. |
| `slotTypes` | Distinct seating areas or services with tables open. |
| `notifyAvailable` | Whether Resy offers its notify list for this date — the fallback when nothing is bookable. |
| `notifyWindows` | The time windows Resy will take notify requests for. |

**Booking calendar — with `includeCalendar`**

| Field | What it is |
|---|---|
| `calendarStart` | First day of the calendar window. Calendar mode only. |
| `calendarEnd` | Last day requested. Calendar mode only. |
| `calendarLastBookableDate` | The furthest date this venue takes bookings for. |
| `calendar` | Day-by-day booking status across the window. Calendar mode only. |
| `availableDates` | Dates in the window with tables open for the party size — the short answer to 'when can I get in?'. |
| `availableDateCount` | How many dates in the window are open. |

**Run metadata**

| Field | What it is |
|---|---|
| `scrapedAt` | When this row was read, ISO 8601 UTC. Availability moves by the minute. |

### Availability semantics

By default, a restaurant with no open tables is **left out** of the results, so
an availability run returns exactly what is bookable. Switch on
`keepUnavailable` to keep every venue with `slotCount: 0` instead — useful when
you want the full list with a booked/not-booked flag.

Party size matters: a table for two and a table for eight are different
questions, and both availability and the calendar are read for `partySize`.

### What an empty result means

An empty dataset is an answer, not a failure. In search mode it means the
restaurant is not on Resy; in availability mode it means nothing is bookable for
that date and party size.

That holds because a broken lookup — a challenge page, a terminal 4xx, retries
exhausted — **fails the run** rather than finishing with nothing. So you can
trust emptiness, and treat a failed run as a retryable error. To tell "booked
solid" from "left Resy", run the same URL without `includeAvailability`.

### Call it from the API

```bash
curl -s "https://api.apify.com/v2/acts/simple.actors~resy-availability/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"city": "New York", "query": "Balthazar", "maxItems": 2}'
```

Swap the input for `{"startUrls": [{"url": "…"}], "includeAvailability": true,
"date": "2026-08-25", "partySize": 2}` to read open tables instead.

### Settings

- **`proxy`** — defaults to Apify datacenter proxy. If Resy starts blocking
  datacenter IPs, switch to
  `{"useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"]}`; the payloads
  are tiny JSON, so residential bandwidth cost stays negligible.
- **`radiusKm`** — restrict search results to one city instead of ranking the
  whole country.
- **`geo` / `locationSlug`** — anchor a search on exact coordinates when a city
  name is not enough.
- **`apiKeyFallback`** — last-known Resy public frontend key, used only if
  reading the current one fails.
- Runs are capped at 256 MB; platform usage is included in the per-result price.

#### The `resy-shared` key-value store

The actor reads Resy's public frontend API key off resy.com and caches it for 12
hours, along with Resy's city table, in a key-value store named `resy-shared`,
so repeated runs don't re-fetch either. This store is created **in your own
account** on first run — that's expected, and it holds nothing but that cache.

### Note

This actor is **not affiliated with, endorsed by, or sponsored by Resy**. It
calls Resy's public frontend API — the same endpoints resy.com's own web client
uses — without a licensing agreement. Review Resy's terms before using it, and
run it at a volume and rate you are comfortable defending.

# Actor input Schema

## `query` (type: `string`):

Restaurant name to search for. Resy ranks matches nationwide with the chosen city first, so 'Carbone' returns the New York, Miami, Dallas and Las Vegas locations — set Search radius to keep results inside one city. Ignored when Venue URLs are set.

## `city` (type: `string`):

City the search is anchored on, e.g. 'Miami', 'Chicago', 'Mexico City', 'Tokyo'. Matched against Resy's own list of 2,000+ markets across the US, Mexico, Spain, Italy, Japan, Canada and more; a city Resy does not cover falls back to New York (override with Geo override).

## `radiusKm` (type: `integer`):

Restrict search results to this many kilometres around the city. Leave empty to rank the whole country by relevance — set it (e.g. 25) when you want only restaurants in that one city.

## `maxItems` (type: `integer`):

Maximum venues to emit (search mode) or URLs to process (URL mode). Search results are paged automatically to reach this number.

## `startUrls` (type: `array`):

Resy venue URLs (https://resy.com/cities/{city}/venues/{slug}). When set, the search inputs are ignored and each URL is read directly.

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

Fetch every bookable table for Date and Party size. Works in both search and URL mode. A venue with no open tables is left out of the results unless Keep unavailable venues is on.

## `date` (type: `string`):

Day to read availability for, YYYY-MM-DD. Required when Include availability is on.

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

Number of guests. Drives both the availability lookup and the calendar — a table for 2 and a table for 8 are different questions.

## `keepUnavailable` (type: `boolean`):

Keep venues that have no open tables, with slotCount 0, instead of leaving them out. Turn this on when you want the full list with a booked/not-booked flag rather than only what is bookable.

## `includeCalendar` (type: `boolean`):

Add a day-by-day calendar showing which dates are available, sold out or closed for Party size — the fastest way to find when a hard-to-book restaurant opens up.

## `calendarStartDate` (type: `string`):

First day of the calendar, YYYY-MM-DD. Defaults to Date if set, otherwise today.

## `calendarDays` (type: `integer`):

How many days of calendar to read from the start date. Resy stops at each venue's own booking horizon, reported back as calendarLastBookableDate.

## `calendarEndDate` (type: `string`):

Last day of the calendar, YYYY-MM-DD. Overrides Calendar length when set.

## `includeRaw` (type: `boolean`):

Attach Resy's untouched JSON for the venue, its availability and its calendar under a `raw` field. Useful when you need a detail this actor does not map to a named field; it makes the output several times larger.

## `locationSlug` (type: `string`):

Advanced: the city path segment Resy uses, e.g. 'new-york-ny'. Search results carry their own, so this is only a fallback for hits that do not; URL mode reads it from the URL.

## `geo` (type: `object`):

Advanced: {"latitude": ..., "longitude": ...} to anchor the search on exact coordinates instead of a city name.

## `apiKeyFallback` (type: `string`):

Advanced: last-known Resy public frontend API key, used only if reading the current one off resy.com fails.

## `proxy` (type: `object`):

Apify Proxy settings. Datacenter (the default) is included in every plan; switch the group to RESIDENTIAL if Resy starts blocking.

## Actor input object example

```json
{
  "query": "Carbone",
  "city": "New York",
  "maxItems": 3,
  "includeAvailability": false,
  "partySize": 2,
  "keepUnavailable": false,
  "includeCalendar": false,
  "calendarDays": 30,
  "includeRaw": false,
  "apiKeyFallback": "VbWk7s3L4KiK5fzlO7JD3Q5EYolJI7n5",
  "proxy": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `venues` (type: `string`):

One row per restaurant: cuisine, rating, price tier, neighborhood and open-table count.

## `openSlots` (type: `string`):

One row per bookable table, unwound from each venue's slots array. Empty for runs that did not request availability.

## `calendar` (type: `string`):

One row per day per restaurant: available, sold out or closed. Empty for runs that did not request the calendar.

## `contact` (type: `string`):

Phone, website, address, coordinates and the Google Place ID you match these venues on.

## `raw` (type: `string`):

Every field of every item, exactly as pushed.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("simple.actors/resy-availability").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("simple.actors/resy-availability").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 '{}' |
apify call simple.actors/resy-availability --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,simple.actors/resy-availability"
        }
    }
}

```

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/KFwjAncXD6GjsvzSQ/builds/QvWl4i9mQAmvVBNmk/openapi.json
