A restaurant availability finder built with Flask. Search for open tables by location, party size, cuisine, time window, and more. Features a dark-themed UI with real-time Resy availability calendars, favorites, watch alerts, and a "Pick one for me" button.
TableScout is a developer-oriented tool. Before installing it, make sure you're comfortable with the following:
You'll need to run commands in a terminal (macOS Terminal, Windows PowerShell, or Linux shell) to install, configure, and start the app. If typing commands like cd, pip install, or editing text files in a terminal is unfamiliar, you may want to brush up on the basics first.
The app requires Python 3.11 or newer. Check your version:
python --versionIf you need to install or upgrade Python, get it from python.org.
You'll need Git to clone the repository. Check with git --version. Install from git-scm.com if needed.
You'll edit a .env file to add API keys and tokens. Any text editor works — VS Code, Notepad++, nano, vim, etc.
To use live Resy availability, you need to copy auth tokens out of your browser's network inspector. This involves:
- Opening DevTools (usually F12 or right-click → Inspect)
- Going to the Network tab
- Finding a specific request and copying a header value
If you've never done this before, search for "how to use browser DevTools Network tab" — it takes about 5 minutes to learn.
TableScout searches for restaurants using up to two sources simultaneously and merges the results:
| Source | What you get | Requires |
|---|---|---|
| Resy | Real restaurants + live time slots | Resy account + auth token |
| Google Places | Real restaurants, no availability | Google Cloud API key |
- Resy results show actual bookable time slots and a 7-day availability calendar.
- Google Places results show restaurant details with an "Availability unknown / Find a Table →" link.
- If neither is configured, the app still runs with generated mock data (useful for testing the UI).
git clone https://github.com/cruftbox/table-scout.git
cd table-scout
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txtcp .env.example .envOpen .env in a text editor and fill in your keys (see sections below). At minimum, set a SECRET_KEY:
SECRET_KEY=any-long-random-string-you-make-up
python app.pyOpen http://localhost:5000 in your browser.
Google Places provides real restaurant names, addresses, ratings, and locations for any area. Without it the app falls back to mock data.
Cost: Free up to 5,000 requests/month, then pay-as-you-go. A typical search uses 1–2 requests.
How to get a key:
- Go to Google Cloud Console and create a project (or use an existing one).
- Go to APIs & Services → Library and enable the Places API.
- Go to APIs & Services → Credentials, click Create Credentials → API Key.
- (Recommended) Restrict the key to the Places API under key restrictions.
- Add to
.env:GOOGLE_PLACES_API_KEY=AIza...your-key-here
Note: Google requires a billing account to be attached to your project, but the free tier is generous and a typical personal-use app won't exceed it.
Resy provides real-time table availability and bookable time slots for restaurants that use the Resy platform. This is the main value-add over Google Places alone.
Cost: Free — you just need a Resy account.
How to get your credentials:
You'll copy two values from your browser's network traffic while logged in to resy.com.
- Log in to resy.com in your browser.
- Open DevTools — press F12, or right-click anywhere on the page and choose Inspect.
- Click the Network tab. If it looks empty, refresh the page.
- In the filter/search box, type
api.resy.comto narrow down the requests. - Click on any request to
api.resy.com. - In the panel that opens, click Headers.
- Scroll down to Request Headers and find:
Authorization— looks likeResyAPI api_key="VbWk7s3L4KiK5fz..."— copy only the value inside the quotes asRESY_API_KEYX-Resy-Auth-Token— a long JWT string starting witheyJ...— copy the whole value asRESY_AUTH_TOKEN
- Add both to
.env:RESY_API_KEY=VbWk7s3L4KiK5fz... RESY_AUTH_TOKEN=eyJ0eXAiOiJKV1Q...
Token expiry: Auth tokens expire periodically (every few weeks to months). If Resy searches stop returning results, repeat steps 1–8 to get a fresh token.
Privacy: These tokens authenticate as your Resy account. Treat them like a password — don't share them or commit them to a public repository.
| Variable | Required | Description |
|---|---|---|
SECRET_KEY |
Yes | Flask session signing key — set to any long random string |
FLASK_DEBUG |
No | Set to true for auto-reload during development |
PORT |
No | Port to run on (default: 5000) |
GOOGLE_PLACES_API_KEY |
Recommended | Enables real restaurant discovery via Google Places |
RESY_API_KEY |
Optional | Enables live Resy availability and booking |
RESY_AUTH_TOKEN |
Optional | Required alongside RESY_API_KEY |
table-scout/
├── app.py # Flask backend — all routes and data logic
├── requirements.txt
├── .env.example # Copy to .env and fill in your values
├── README.md
├── templates/
│ └── index.html # Single-page app template
└── static/
├── css/
│ └── style.css # Dark navy + amber theme
└── js/
└── app.js # All client-side interactivity (vanilla JS)
- Session state (favorites, watches, recent searches) uses Flask's signed cookie session — no database required.
- The watch-alert poller runs client-side every 5 minutes via
setInterval. - Resy and Google Places searches run concurrently and are merged, with duplicates removed by name and proximity.
- Google Places results link to the restaurant's website or Google Maps; availability must be checked directly.