# Restaurant, Cafe & Bar Scraper: Email, Phone & Address (`scrapebench/restaurant-leads-scraper`) Actor

Every restaurant, cafe, bar and bakery in a US state, county, city or ZIP code: phone, email, website, address, cuisine, hours, reservation and online-ordering platform, rating. From Google Maps and each place's own website.

- **URL**: https://apify.com/scrapebench/restaurant-leads-scraper.md
- **Developed by:** [ScrapeBench](https://apify.com/scrapebench) (community)
- **Categories:** Lead generation
- **Security:** Limited permissions
- **Stats:** 4 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.003 / restaurant

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/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

## Restaurant, Cafe & Bar Scraper: Email, Phone & Address

### Pain points

- A Google Maps search for "restaurant in 10001" (Manhattan) stops at 147 places and only 61 of them are in that ZIP code; the actor's split search found 636 food and drink places there (2026-10-30).
- Generic Google Maps scrapers make you run "restaurant", "cafe", "bar" and "bakery" as separate searches, merge the duplicates and filter out the gas stations and grocery stores yourself.
- Knowing which restaurants already take orders through Toast, DoorDash or ChowNow means opening every website one by one.
- Copying restaurants out of Google Maps into a spreadsheet takes days for a single county.

### What we solve

- One input for the whole job: a state, plus optional counties, cities or ZIP codes, and the type of place. The actor works out the ZIP codes and the searches.
- Searches ZIP code by ZIP code and splits a busy ZIP code into smaller map squares, so a downtown comes back complete instead of stopping at Google's limit for one search.
- Restaurants, cafes, coffee shops, bars, bakeries and fast food in one run, or one kind only; only food and drink places, only inside your area, once each (deduplicated by Google's place ID).
- An email lookup on each place's own website (on by default, can be switched off), charged only when an email is found, which also reports the ordering, delivery and POS platforms the site uses.

### Summary

Pick a state, and optionally counties, cities or ZIP codes, and get every restaurant, cafe, bar and bakery Google Maps lists there, or only one kind: one row per place with its name, type, phone number, website, street address, city, county, ZIP code, cuisine categories, weekly opening hours, the booking platform Google links (OpenTable, Resy, Tock, Toast Tables), Google rating, review count, coordinates and a Google Maps link. One Google Maps search stops at about 160 places, which leaves out most of a busy downtown, so the actor searches your area ZIP code by ZIP code, and where a ZIP code still runs into that limit it splits the map into smaller squares until each one comes back complete. It keeps only food and drink places inside your area and removes duplicates by Google's own place ID. By default it also visits each place's own website and returns the email published there, plus the online-ordering, delivery and POS platforms the site uses or links to (Toast, DoorDash, Uber Eats, ChowNow, Square and others).

### Who it's for

- Restaurant software and POS sales teams (ordering, payments, reservations, payroll) building a territory
- Food and beverage distributors, coffee roasters and breweries prospecting new accounts
- Delivery, marketing and review-management agencies working with local restaurants
- Insurance, payment-processing, linen and equipment-leasing reps prospecting restaurants

### How to use

Set the input, run the actor, and collect results from the run's dataset (export to JSON/CSV/Excel, or pull via the Apify API). Example input:

```json
{
  "state": "CA",
  "cities": [
    "Lafayette"
  ],
  "placeType": "restaurant",
  "includeEmails": true
}
```

See **Inputs** below for every available field.

### What you get

One row per record:

| Field | Description |
|---|---|
| `name` | The place's name on Google Maps |
| `business_type` | restaurant, cafe, bar, bakery or fast_food, from Google's categories |
| `phone` | Phone number as Google Maps lists it |
| `email` | The place's email from its own website (null when none was found or the lookup is switched off) |
| `emails` | Every address of the place's own found on its website |
| `website` | The website the place lists on Google Maps |
| `online_ordering` | Ordering, delivery and POS platforms the website is on or links to (Toast, DoorDash, Uber Eats, ChowNow, Square, ...) |
| `reservation_platform` | Where Google Maps' booking link goes: OpenTable, Resy, Tock, Toast Tables, or "Own website" |
| `reservation_url` | The place's page on that booking platform |
| `address` | Full street address |
| `street` | Street line(s) |
| `city` | City |
| `county` | County of the place's ZIP code |
| `state` | Two-letter state code |
| `zip_code` | 5-digit ZIP code |
| `categories` | Google Maps categories (cuisine), primary first |
| `rating` | Google rating, 1 to 5 |
| `review_count` | Number of Google reviews |
| `opening_hours` | Weekly hours by day, Monday first |
| `description` | Google's one-line summary of the place, where it has one |
| `badges` | Attributes the owner declared on Google, such as "Identifies as women-owned" |
| `latitude` | Latitude |
| `longitude` | Longitude |
| `place_id` | Google's own place ID, unique per row |
| `google_maps_url` | Opens the place on Google Maps |
| `source_url` | Where the row came from (its Google Maps link) |

Sample:

```json
{
  "name": "360 Gourmet Burritos",
  "business_type": "restaurant",
  "phone": "(925) 299-1270",
  "email": null,
  "emails": [],
  "website": "https://www.360burrito.com/",
  "online_ordering": [
    "ChowNow"
  ],
  "reservation_platform": null,
  "reservation_url": null,
  "address": "3655 Mount Diablo Blvd, Lafayette, CA 94549",
  "street": "3655 Mount Diablo Blvd",
  "city": "Lafayette",
  "county": "Contra Costa",
  "state": "CA",
  "zip_code": "94549",
  "categories": [
    "Mexican restaurant",
    "Burrito restaurant"
  ],
  "rating": 4.5,
  "review_count": 122,
  "opening_hours": {
    "Monday": "10:30 AM-7:30 PM",
    "Tuesday": "10:30 AM-7:30 PM",
    "Wednesday": "10:30 AM-7:30 PM",
    "Thursday": "10:30 AM-7:30 PM",
    "Friday": "10:30 AM-7:30 PM",
    "Saturday": "10:30 AM-6:30 PM",
    "Sunday": "Closed"
  },
  "description": null,
  "badges": [],
  "latitude": 37.8906477,
  "longitude": -122.1277167,
  "place_id": "ChIJ19DWkldihYARuoIvQ2paBt0",
  "google_maps_url": "https://www.google.com/maps/search/?api=1&query=360%20Gourmet%20Burritos&query_place_id=ChIJ19DWkldihYARuoIvQ2paBt0",
  "source_url": "https://www.google.com/maps/search/?api=1&query=360%20Gourmet%20Burritos&query_place_id=ChIJ19DWkldihYARuoIvQ2paBt0"
}
```

### Inputs

| Field | Required | Type | Default | Description |
|---|---|---|---|---|
| `state` | no | string | `"CA"` | The US state to search. On its own it searches the whole state; add counties, cities or ZIP codes below to narrow it. |
| `counties` | no | array | `[]` | Only these counties of the state, e.g. Contra Costa or Harris. "County" is optional and spelling is forgiving. A name that is not in the state is skipped and a free row lists the real names. |
| `cities` | no | array | `["Lafayette"]` | Only these cities, by their postal name, e.g. Lafayette or Houston. A big city is searched ZIP code by ZIP code, and a busy ZIP code is split into smaller map areas, so nothing is lost to Google's limit on one search. |
| `zipCodes` | no | array | `[]` | Only these 5-digit ZIP codes. Combined with counties and cities if you fill more than one. |
| `placeType` | no | string | `"restaurant"` | "All restaurants, cafes, bars & bakeries" returns every food and drink place. Pick one of the others to get only that kind. |
| `includeEmails` | no | boolean | `true` | On by default: visit each place's own website, return the email published there and the online-ordering platforms it links to. The email is charged separately, only for places where one is found. Turn it off for phone and address only. |
| `maxResults` | no | integer | `1000` | Cap on the number of places returned for the WHOLE run (not per city or county). A spend cap: the run stops once it has this many. |
| `maxPagesPerSite` | no | integer | `6` | How many pages of each place's website the email lookup reads: the homepage plus its contact and about pages. |
| `proxyConfiguration` | no | object | `{"useApifyProxy": true}` | Apify's datacenter proxy by default, which is what this actor was tested with. |

### Pricing (Pay Per Event)

You pay per result (`restaurant`) — **no charge for empty runs**. Example: **1000 restaurants** at *$0.003/result* ≈ **$3.00**.

The email lookup is on by default and charged separately (switch it off with "Look up each place's email"): $0.002 per place where an email is found on its website (event "Email found"); a place with no email found costs nothing extra. The ordering-platform check comes with the lookup at no charge. Searches go through Apify Proxy, billed by Apify as platform usage on your plan, like compute.

### Use cases

- Build a territory list: every restaurant in the counties a sales rep covers, with phone numbers and emails, in one run.
- Find switch prospects: restaurants whose website runs on a competitor's ordering or POS platform, or on none.
- Market sizing: count restaurants, cafes and bars per county or ZIP code, with cuisine, ratings and review counts, before opening a location or launching a product.
- Keep a CRM current: re-run a county each month and compare place IDs to spot new and closed restaurants.

### Why this actor

- Complete big cities: ZIP code by ZIP code, and busy ZIP codes split into smaller map squares, never one capped city search.
- Restaurants, cafes, bars and bakeries in one run, sorted by type, only food and drink places, only in your area, once each.
- Ordering and POS platform from each place's own website, and the booking platform from Google Maps, in the same row as the email and phone.

### Limitations & updates

Covers the 50 US states and DC. Data is what Google Maps publishes about each place at the time of the run: a place with no phone or website on Google Maps has none here, Google's categories decide what counts as each type, and Google Maps does not publish a price level or delivery links in this view, so neither is returned. In the densest downtown ZIP codes the map split finds most but not every place (in Manhattan's 10001, about 80% of what a much slower brute-force grid of searches found, 2026-10-30). The email and ordering-platform lookup reads only the place's own public website (homepage plus contact/about pages), does not guess or verify addresses, and skips Facebook and Instagram pages. ZIP-to-county data is the GeoNames US postal-code file (CC BY 4.0).

### FAQ

**What area can I search?**

Any US state (plus DC). On its own, the state searches the whole state; add counties, cities or 5-digit ZIP codes to narrow it, and they combine. County names are forgiving ("Contra Costa" or "Contra Costa County"); a name that is not in the state is skipped, and a free row lists the real names.

**Why ZIP code by ZIP code, and what is the map split?**

One Google Maps search stops at about 160 places. The actor searches each ZIP code near its own centre and keeps only places whose address ZIP is in your area. Where a ZIP code's search still ends at Google's limit, the actor searches that ZIP code again in four smaller map squares, and splits again where needed. Measured in Manhattan's 10001 on 2026-10-30: one search found 61 restaurants in that ZIP code; the actor found 636 food and drink places there.

**Which places are included?**

With "All restaurants, cafes, bars & bakeries" (the default): every place whose main Google category is food or drink, from restaurants of every cuisine to coffee shops, bars, pubs, breweries, bakeries, dessert shops and fast food. Gas stations, hotels and grocery stores are left out even when they serve food, because Google files them under their main business. Pick "Cafes & coffee shops", "Bars & pubs", "Bakeries & desserts" or "Fast food" to get only that kind. Every row carries a business_type, so you can also filter an "All" export afterwards.

**How does the email and ordering-platform lookup work?**

Unless you switch "Look up each place's email" off, the actor reads the homepage and contact/about pages of each place's own website (up to 6 pages by default), returns the emails published there, and lists the ordering, delivery and POS platforms the pages link to or load (Toast, DoorDash, Uber Eats, Grubhub, ChowNow, Square, Clover, SpotOn and others). Platform and booking-site addresses are dropped. Chain locations often publish only the chain's head-office address, and the actor returns what the site publishes. Places whose website is a Facebook or Instagram page are skipped.

**How many places have an email?**

Fewer than have a phone. In Lafayette, CA (2026-10-30): 91 places, 86 with a phone, 74 with a website, 29 with an email found on their site, and 19 with an ordering platform.

**How am I charged?**

$0.003 per place returned. With the email lookup on (the default), another $0.002 per place where an email was found; no email found, no extra charge. Free rows (a refused search, an unknown county, input to fix) are never charged. Set "Maximum places" to cap a run's spend.

**How long does a run take?**

Measured on 2026-10-30: Lafayette, CA (1 ZIP code, 91 places) in about 80 seconds with the email lookup; Manhattan's 10001, the densest ZIP code we know of (636 places), in about 4 minutes of searching; all of Contra Costa County, CA (52 ZIP codes, 3,387 places) in about 21 minutes of searching, before the email lookup. A whole state runs for hours; set "Maximum places" or narrow the area, and raise the run timeout for a big area.

**What if Google refuses a search?**

Each search is retried on a fresh proxy address. If a ZIP code still fails, the places found elsewhere are delivered and a free row lists the ZIP codes to run again, so a refusal never reads as "no restaurants here".

### Which actor to choose

Works with:

- **Business Email, Phone & Contact Details Scraper** — You already have a list of websites and want email, phone and social links for each.
- **Nail Salon & Spa Scraper: Email, Phone & Address** — You want the same kind of list for nail salons, nail spas and nail studios.

### Guides & use cases

Written up on **[scrapebench.dev](https://scrapebench.dev)** — the bench that runs and verifies this actor against the live source every night:

- **How-to:** [How to run Restaurant, Cafe & Bar Scraper: Email, Phone & Address](https://scrapebench.dev/guides/how-to-restaurant-leads-scraper/)
- **Use case:** [Find Restaurants by the Online-Ordering Platform They Use](https://scrapebench.dev/use-cases/restaurants-by-ordering-platform/)

More actors, coverage and nightly verification results: **[scrapebench.dev](https://scrapebench.dev)**

### Works with AI assistants (MCP)

Callable as an MCP tool, so Claude, Cursor, VS Code Copilot and other MCP clients can run it directly. Grab the config from the [MCP tab](https://apify.com/scrapebench/restaurant-leads-scraper/api/mcp) on this page — Apify hosts the server and keeps that snippet current, and OAuth signs you in on first connect, so no API token goes in your config file.

Then just ask:

> "Find every restaurant in Lafayette, California, with its phone number, email and the online-ordering platform it uses."

One city is a small first call (about 90 places). Widen it to a county, or narrow it to one type of place, once the rows look right. Runs started this way bill exactly like any other run.

### Data & lawful use

This actor collects publicly available information that Google (Google Maps) and the restaurants' own websites publishes for public
lookup — licence records, business listings and the contact details professionals list there.
Some of it identifies individuals (sole proprietors, licence holders, agents), so treat any
names, phone numbers and emails in your results as personal data.

When you run this actor, you decide what is collected and what it is used for, so you are the
controller of that data and we act only as your processor (Apify Standard Actor Contract).
You need a lawful basis for your use, must honour opt-out and deletion requests, and must
follow the marketing rules that apply to you (CAN-SPAM, TCPA, GDPR, CCPA and similar).
Don't use the output for unsolicited bulk messaging, for screening covered by the FCRA, or
for anything the source's own terms forbid.

Your results are stored in your own Apify account. We don't keep a copy of your results and
don't sell or share them.

### Disclaimer

This is an independent tool. It is not affiliated with, endorsed by or sponsored by
Google (Google Maps) and the restaurants' own websites. Names and marks are used only to describe the data source. Records are
provided as published by the source and may be out of date or incomplete. For anything
consequential (hiring, a permit, a legal decision), confirm the record with the issuing
agency. You are responsible for making sure your use complies with applicable law and the
source's terms.

### Need help?

Open an issue on this actor's **Issues** tab and we'll respond there. Bug reports, missing
fields and feature requests are all welcome. Guides and examples: [scrapebench.dev](https://scrapebench.dev).

If you are a person named in this data and want your record removed from our copy, email
apify-help@scrapebench.dev; the source agency remains the official record.

Your run may be used to improve our services. If something looks off, or you want this actor to fit your use better, please share your run data with us: [Apify Console → Settings → Security → Share run data with developers](https://console.apify.com/settings/security). It lets us see exactly what went wrong and keep improving the actor.

# Actor input Schema

## `state` (type: `string`):

The US state to search. On its own it searches the whole state; add counties, cities or ZIP codes below to narrow it.

## `counties` (type: `array`):

Only these counties of the state, e.g. Contra Costa or Harris. "County" is optional and spelling is forgiving. A name that is not in the state is skipped and a free row lists the real names.

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

Only these cities, by their postal name, e.g. Lafayette or Houston. A big city is searched ZIP code by ZIP code, and a busy ZIP code is split into smaller map areas, so nothing is lost to Google's limit on one search.

## `zipCodes` (type: `array`):

Only these 5-digit ZIP codes. Combined with counties and cities if you fill more than one.

## `placeType` (type: `string`):

"All restaurants, cafes, bars & bakeries" returns every food and drink place. Pick one of the others to get only that kind.

## `includeEmails` (type: `boolean`):

On by default: visit each place's own website, return the email published there and the online-ordering platforms it links to. The email is charged separately, only for places where one is found. Turn it off for phone and address only.

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

Cap on the number of places returned for the WHOLE run (not per city or county). A spend cap: the run stops once it has this many.

## `maxPagesPerSite` (type: `integer`):

How many pages of each place's website the email lookup reads: the homepage plus its contact and about pages.

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

Apify's datacenter proxy by default, which is what this actor was tested with.

## Actor input object example

```json
{
  "state": "CA",
  "counties": [],
  "cities": [
    "Lafayette"
  ],
  "zipCodes": [],
  "placeType": "restaurant",
  "includeEmails": true,
  "maxResults": 1000,
  "maxPagesPerSite": 6,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One row per place: name, type, phone, email, website, ordering and reservation platforms, address, county, cuisine, hours, rating, Google Maps link.

# 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 = {
    "state": "CA",
    "cities": [
        "Lafayette"
    ],
    "placeType": "restaurant",
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapebench/restaurant-leads-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 = {
    "state": "CA",
    "cities": ["Lafayette"],
    "placeType": "restaurant",
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapebench/restaurant-leads-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 '{
  "state": "CA",
  "cities": [
    "Lafayette"
  ],
  "placeType": "restaurant",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapebench/restaurant-leads-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapebench/restaurant-leads-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/bVhgpP6L3EcFkSKKy/builds/dG7DG6getMqWFHIou/openapi.json
