Resy Availability Checker: Open Tables by Date & Party Size
Pricing
from $0.69 / 1,000 availability checkeds
Resy Availability Checker: Open Tables by Date & Party Size
Read-only Resy table availability: paste restaurant URLs, pick dates and a party size, get one row per restaurant per date with Resy's calendar status and every open slot (time, seating type). Schedule it to alert when a hard-to-book table opens. Never books.
Pricing
from $0.69 / 1,000 availability checkeds
Rating
0.0
(0)
Developer
Superslow Sloth
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Paste the restaurants you cannot get into, pick the dates and a party size, and
get one row per restaurant per date from Resy: Resy's own
calendar status for a reservation (available, sold-out, closed), the
list of open slots (start, end, seating type) and the date it was read.
Schedule it every few minutes with a webhook on Only dates with open tables
and it becomes a cancellation alert for hard-to-book tables.
Read-only. This actor only reads availability. It never books, holds or cancels a table, needs no Resy account, and does not log in. It leaves out the one value Resy puts on each slot that exists to make a booking (see below).
No account, no API key, no browser. One calendar request per restaurant, plus one availability request per date that is actually open.
Input
| Field | Notes |
|---|---|
venues | One restaurant per line: its resy.com page https://resy.com/cities/ny/venues/lilia, the short form ny/lilia, or Resy's numeric venue id 418. The same restaurant given twice is checked once. |
partySize | How many guests (1 to 30, default 2). Sent to Resy on every call; each row carries the restaurant's own minimum and maximum party, and the log warns when yours is outside them. |
dates | Specific dates, YYYY-MM-DD, one per line, on the restaurant's own calendar. |
startDate, daysAhead | Used when dates is empty: daysAhead consecutive days (default 14, up to 120) from startDate, which defaults to today on each restaurant's own clock (a New York restaurant at 10 pm Eastern is still on the day before in UTC). |
timeFrom, timeTo | Only count slots starting inside this window, 24-hour HH:MM on the restaurant's clock, both ends inclusive. |
seatingTypes | Only count slots in these areas, named as Resy names them (Dining Room, Bar, Patio, Indoor...), case ignored. |
onlyAvailable | Keep only rows with at least one slot, so a run that finds nothing leaves an empty dataset. Every date is still checked and charged. |
maxItems | Check at most this many restaurant-dates (default 500, up to 5,000). |
proxyConfiguration | Apify datacenter proxy, the default. |
Example input, a weekend dinner alert:
{"venues": ["https://resy.com/cities/ny/venues/lilia","ny/carbone"],"partySize": 2,"dates": ["2026-11-06", "2026-11-07", "2026-11-13", "2026-11-14"],"timeFrom": "18:00","timeTo": "21:30","seatingTypes": ["Dining Room", "Indoor"],"onlyAvailable": true}
A line that is not a Resy restaurant, a date that is not YYYY-MM-DD, a date in
the past, or a time that is not HH:MM stops the run before anything is
charged, with the line named.
Output
One row per restaurant per date. Real values from 2026-10-20, slots shortened
to two of 14:
{"query": "https://resy.com/cities/ny/venues/lilia","venue_id": 418,"venue_name": "Lilia","venue_slug": "lilia","venue_url": "https://resy.com/cities/new-york-ny/venues/lilia","cuisine": "Italian","city": "Brooklyn","neighborhood": "Williamsburg","region": "NY","city_code": "ny","time_zone": "EST5EDT","min_party_size": 2,"max_party_size": 6,"date": "2026-10-20","party_size": 2,"calendar_status": "available","walk_in_status": "available","event_status": "not available","available": true,"slots_checked": true,"slot_count": 14,"slots": [{"start": "2026-10-20 17:00:00", "end": "2026-10-20 19:00:00", "type": "Bar", "party_min": 2, "party_max": 2, "is_paid": false},{"start": "2026-10-20 17:00:00", "end": "2026-10-20 19:00:00", "type": "Indoor", "party_min": 2, "party_max": 2, "is_paid": false}],"checked_at": "2026-10-20T16:00:00Z"}
| Field | Notes |
|---|---|
query, venue_id, venue_name, venue_slug, venue_url | The line you gave and the restaurant Resy resolved it to. |
cuisine, city, neighborhood, region, city_code, time_zone | From Resy's venue record. city is Resy's locality (Lilia is in Brooklyn although Resy files it under New York), city_code is Resy's short code (ny). |
min_party_size, max_party_size | The restaurant's own bounds. A party outside them gets no slots. |
date, party_size | What was checked. |
calendar_status | Resy's word for a reservation on that date, as sent: available, sold-out, closed or not available (event-only dates). not-scheduled is this actor's word, not Resy's: the date is not on the restaurant's calendar at all (not released yet, or past its booking window). |
walk_in_status, event_status | Resy's words for walk-in and event seating on that date, as sent; null when the date is not on the calendar. A sold-out date can still list walk-ins. |
available | true when slots holds at least one slot after your time and seating filters. The field to alert on. |
slots_checked | Whether the availability call was made for this date (see below). An empty slots is never ambiguous. |
slot_count, slots | Each slot: start and end as Resy sends them (the restaurant's local clock, no zone, YYYY-MM-DD HH:MM:SS), type (the seating area), party_min and party_max (the parties the slot seats), and is_paid (Resy's flag for a slot that takes a payment or deposit; null when absent). |
checked_at | When the check ran, UTC. |
What is left out, and why
Each slot Resy returns carries a config.token (rgs://resy/...). It is the
handle the booking call takes for that exact slot. This actor only reads
availability, so that booking token is not copied into the dataset: a dataset
is often shared, exported and posted to webhooks, and nothing in an availability
alert needs the one value that exists to make a reservation.
How it reads Resy, and the calendar shortcut
For each restaurant: one request resolves it (name, city, time zone, party
bounds), one request reads its calendar for the whole date range, and the
availability call is made only for dates the calendar calls available.
Measured 2026-10-20 on three restaurants, comparing the calendar with Resy's
availability answer for the same date: every sold-out date (5 of 5) came back
with no slots, every closed date (2 of 2) came back with no venue at all, the
one event-only date (reservation not available) came back with no slots, and
every available date (3 of 3) had slots. So a sold-out or closed date costs one
cheap calendar entry instead of a 13 to 39 KB availability answer, and the log
says how many availability reads were skipped. A calendar word the actor has not
seen before is read with the availability call rather than guessed at.
Resy only lists the dates a restaurant has scheduled: Carbone's calendar on
2026-10-20 ran to 2026-11-18 plus two event-only dates, and Lilia's to 2026-11-15
(27 dates). The dates in between and after are not-scheduled. The restaurants'
booking windows ran from 19 to 66 days in the three measured, so a high
daysAhead is mostly not-scheduled rows; they are still checked, and charged,
like any other date.
Pricing
Pay per event: $0.00069 per date checked plus $0.002 per run start. One
date at one restaurant is one check, whatever its status: a sold-out date costs
the same as a date with twenty slots, because "nothing is open" is the answer an
alert is waiting for, and the price is knowable before the run (restaurants times
dates). 2 restaurants over 14 days is 28 checks, $0.021. onlyAvailable changes
which rows are kept, not what is charged. A restaurant Resy does not have, a date
whose availability could not be read after retries, a duplicate line, or a date
past maxItems is not charged.
Where it runs, and what the API key is
Nothing here is scraped from a rendered page: it calls the same JSON API that
resy.com's own page calls, using the public web key that resy.com's JavaScript
embeds (apiKey in modules/app.<hash>.js). It is not a secret and not tied to
an account. Resy can rotate it; when it does, every call answers HTTP 419
Unauthorized. The actor then reads the current key from resy.com's own bundle
once, logs that it did, and goes on. If no different key can be read the run
fails with a message saying the key was rejected, instead of returning empty
rows.
Measured 2026-10-20: Apify datacenter addresses answered the calendar, venue and availability calls 9 of 9 (HTTP 200); the Apify residential proxy answered 4 of 5, one connection reset. The default is the automatic datacenter proxy. From a single non-Apify address, the availability call began answering an empty HTTP 500 after about 45 requests in 45 minutes while the venue and calendar calls kept answering, so a refused request (403, 429, 5xx, an empty or non-JSON 200) is treated as that address being blocked: the actor rotates to a fresh address and retries before giving up on that date.
One header detail, measured the same day: the calendar call answers an empty HTTP
500 when the request carries a Referer header (3 of 3), and answers 200 when it
does not (3 of 3). The actor sends the key and Origin only.
Limits worth knowing:
- Slot times are the restaurant's local clock with no zone.
time_zoneis Resy's zone name for the restaurant. - The availability call is per party size; a party the restaurant cannot seat gets no slots even on an open date.
- Some venues sell tickets, prix-fixe seatings or events outside the standard
reservation flow; those show up as the
event_status, not asslots. - If Resy changes its answer's shape the run fails that date with a message instead of returning empty rows.