# Nail Salon & Spa Scraper: Email, Phone & Address (`scrapebench/nail-salon-leads-scraper`) Actor

Every nail salon, nail spa and nail studio in a US state, county, city or ZIP code: name, phone, website, address, county, rating and reviews from Google Maps, plus each shop's email from its own website.

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

## Pricing

from $0.003 / nail shop

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

## Nail Salon & Spa Scraper: Email, Phone & Address

### Pain points

- A Google Maps search for "nail salon in Houston" stops at about 150 shops, so a city-wide list is never complete.
- Generic Google Maps scrapers make you build the search terms, merge the duplicates and filter out hair salons and supply stores yourself.
- Most nail shops' email is a Gmail or Yahoo address on their own website, and generic email finders either flag it as "not the business's domain" or mix in the booking platform's and the franchise's addresses.
- Copying shops one by one out of Google Maps into a spreadsheet takes hours for a single county.

### What we solve

- One input for the whole job: a state, plus optional counties, cities or ZIP codes. The actor works out the ZIP codes and the searches.
- Searches ZIP code by ZIP code, so a big city comes back complete instead of stopping at Google's limit for one search.
- Keeps only nail shops, inside your area, once each (deduplicated by Google's place ID).
- An email lookup on each shop's own website (on by default, can be switched off) that keeps the shop's inbox and drops platform and franchise addresses, charged only when an email is found.

### Summary

Pick a state, and optionally counties, cities or ZIP codes, and get every nail salon, nail spa and nail studio Google Maps lists there: one row per shop with its name, phone number, website, street address, city, county, ZIP code, Google rating, review count, categories, coordinates and a Google Maps link. One Google Maps search stops at about 150 places, which undercounts any big city, so the actor splits your area into its ZIP codes, searches each one, keeps only shops whose address falls inside your area, and removes duplicates by Google's own place ID. By default it also visits each shop's own website and returns the email published there, keeping the shop's own inbox (including the Gmail and Yahoo addresses most nail shops use) and dropping booking-platform, franchise-headquarters and template addresses.

### Who it's for

- Nail-supply and beauty-product distributors building a sales territory
- Sales teams selling salon software (booking, POS, payroll) to independent nail shops
- Marketing agencies running local campaigns for beauty businesses
- Insurance, payment-processing and equipment-leasing reps prospecting small salons

### 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"
  ],
  "includeEmails": true
}
```

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

### What you get

One row per record:

| Field | Description |
|---|---|
| `name` | The shop's name on Google Maps |
| `phone` | Phone number as Google Maps lists it |
| `email` | The shop's email from its own website (null when none was found or the lookup is switched off) |
| `emails` | Every address of the shop's own found on its website |
| `website` | The website the shop lists on Google Maps |
| `address` | Full street address |
| `street` | Street line(s) |
| `city` | City |
| `county` | County of the shop's ZIP code |
| `state` | Two-letter state code |
| `zip_code` | 5-digit ZIP code |
| `rating` | Google rating, 1 to 5 |
| `review_count` | Number of Google reviews |
| `categories` | Google Maps categories, primary first |
| `latitude` | Latitude |
| `longitude` | Longitude |
| `place_id` | Google's own place ID, unique per row |
| `google_maps_url` | Opens the shop on Google Maps |
| `source_url` | Where the row came from (its Google Maps link) |

Sample:

```json
{
  "name": "Chloe Nails Lounge",
  "phone": "(925) 299-6779",
  "email": "chloetran112@gmail.com",
  "emails": [
    "chloetran112@gmail.com"
  ],
  "website": "https://chloenailslounge.com/",
  "address": "3570 Mount Diablo Blvd, Lafayette, CA 94549",
  "street": "3570 Mount Diablo Blvd",
  "city": "Lafayette",
  "county": "Contra Costa",
  "state": "CA",
  "zip_code": "94549",
  "rating": 4.6,
  "review_count": 117,
  "categories": [
    "Nail salon"
  ],
  "latitude": 37.8920232,
  "longitude": -122.1210429,
  "place_id": "ChIJTaBKdlpihYARTMjamFFwOwY",
  "google_maps_url": "https://www.google.com/maps/search/?api=1&query=Chloe%20Nails%20Lounge&query_place_id=ChIJTaBKdlpihYARTMjamFFwOwY",
  "source_url": "https://www.google.com/maps/search/?api=1&query=Chloe%20Nails%20Lounge&query_place_id=ChIJTaBKdlpihYARTMjamFFwOwY"
}
```

### 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, 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. |
| `includeEmails` | no | boolean | `true` | On by default: visit each shop's own website and return the email published there. Charged separately, only for shops where an email is found. Adds a few seconds per website; turn it off for phone and address only. |
| `maxResults` | no | integer | `1000` | Cap on the number of shops 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 shop'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 (`salon`) — **no charge for empty runs**. Example: **1000 nail shops** at *$0.003/result* ≈ **$3.00**.

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

### Use cases

- Build a territory list: every nail shop in the counties a sales rep covers, with phone numbers, in one run.
- Email outreach: the shop's own inbox, found on its website, for a cold-email campaign.
- Market sizing: count nail shops per county or ZIP code, with 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 shops.

### Why this actor

- Complete big cities: searched ZIP code by ZIP code, never one capped city search.
- Only nail shops, only in your area, once each, keyed on Google's place ID.
- A salon-aware email lookup: keeps the shop's own Gmail or Yahoo inbox, drops booking-platform and franchise-HQ addresses, and costs nothing when no email is found.

### Limitations & updates

Covers the 50 US states and DC. Data is what Google Maps publishes about each shop at the time of the run: a shop with no phone or website on Google Maps has none here, and Google's categories decide most of what counts as a nail shop. The email lookup reads only the shop's own public website (homepage plus contact/about pages), does not guess or verify addresses, and skips Facebook and Instagram pages. Within each ZIP code the actor searches "nail salon" and adds "nail spa" and "nail studio" where that first search reaches Google's limit; in a 10-ZIP test this found 96% of what all three terms found everywhere. 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?**

One Google Maps search stops at about 150 places (we measured 163 for "nail salon in Houston, TX" and 150 for Lafayette, CA on 2026-10-30). The actor searches each ZIP code in your area near its own centre and keeps only shops whose address ZIP is in your area, so a big city is not cut off.

**Which businesses count as nail shops?**

Places Google Maps files under a nail category ("Nail salon" and similar), plus shops with "nail" in their own name that Google files under something broader, like "Beauty salon". Nail-supply stores are left out. You do not pick salon, spa or studio; all three are included.

**How does the email lookup work?**

Unless you switch "Look up each shop's email" off, the actor reads the homepage and contact/about pages of each shop's own website (up to 6 pages by default) and returns the emails published there. It keeps the shop's own address, including the Gmail, Yahoo and AOL inboxes most nail shops use, and drops booking-platform addresses (Vagaro, GlossGenius, Square), suite-chain and franchise headquarters inboxes, and template placeholders. Shops whose website is a Facebook or Instagram page are skipped.

**How many shops have an email?**

Fewer than have a phone. Across Contra Costa County, CA (2026-10-30), 33% of the shop websites we could reach published an email, which is 17% of all shops; 95% of shops had a phone number and 55% a website.

**How am I charged?**

$0.003 per nail shop returned. With the email lookup on (the default), another $0.002 per shop 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 shops" to cap a run's spend.

**How long does a run take?**

Measured on 2026-10-30: Contra Costa County, CA (52 ZIP codes, 452 shops) in about 13 seconds of searching, and the whole of Oregon (481 ZIP codes, 1,371 shops) in about 48 seconds. The email lookup adds a few seconds per website.

**What if Google refuses a search?**

Each search is retried on a fresh proxy address. If a ZIP code still fails, the shops found elsewhere are delivered and a free row lists the ZIP codes to run again, so a refusal never reads as "no salons 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.

### 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 Nail Salon & Spa Scraper: Email, Phone & Address](https://scrapebench.dev/guides/how-to-nail-salon-leads-scraper/)
- **Use case:** [Find Every Nail Salon in a Sales Territory, With Phone Numbers](https://scrapebench.dev/use-cases/nail-salon-sales-territory-list/)

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/nail-salon-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 nail salon in Lafayette, California, with its phone number and email."

One city is a small, fast first call (about 20 shops). Widen it to a county, or the whole state, 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 shops' 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 shops' 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, 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.

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

On by default: visit each shop's own website and return the email published there. Charged separately, only for shops where an email is found. Adds a few seconds per website; turn it off for phone and address only.

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

Cap on the number of shops 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 shop'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": [],
  "includeEmails": true,
  "maxResults": 1000,
  "maxPagesPerSite": 6,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One row per shop: name, phone, optional email, website, address, county, 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"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapebench/nail-salon-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"],
    "proxyConfiguration": { "useApifyProxy": True },
}

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapebench/nail-salon-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/HEk0iWhhSOlQTIxN1/builds/9TzwQgPqehh74Yri2/openapi.json
