# Fresha Scraper — Salon, Spa & Beauty Business Leads (`scrapesage/fresha-scraper`) Actor

Scrape Fresha salons, spas, barbers, nail & beauty/wellness businesses by category and city, or from venue URLs. Get name, phone, address, geo, rating & reviews, full service menu with prices, team, hours, amenities and a lead score. Monitoring, no login, no key, no browser.

- **URL**: https://apify.com/scrapesage/fresha-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** Lead generation, Automation, Other
- **Stats:** 3 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.00 / 1,000 venue scrapeds

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

## Fresha Scraper — Salon, Spa & Beauty Business Leads (Phones, Services & Prices)

Extract **complete beauty & wellness business data from Fresha** — salons, spas, barbershops, nail bars, medspas, massage, tattoo studios, gyms and more. Get the fields lead lists actually need: **business name, phone, full address + geo, star rating & review count, the full service menu with prices, team members, opening hours and amenities** — plus the venue's **own website** (for unclaimed listings) and optional **email/social enrichment**.

No login, no API key, no browser — fast JSON extraction with 99%+ reliability, worldwide.

### Why this Fresha scraper?

Most beauty scrapers return a name and an address and stop. This actor reads Fresha's own page data and ships the **richest record in the category**, across **both** Fresha venue types:

| Data | Typical scrapers | This actor |
|---|---|---|
| Business name, address, geo (lat/lng) | ✅ | ✅ |
| Phone number | partial | ✅ |
| Star rating + review count | partial | ✅ |
| **Rating distribution (1–5★ breakdown)** | ❌ | ✅ |
| **Full service menu with prices & durations** | ❌ | ✅ |
| **Team members + job titles** | ❌ | ✅ |
| Opening hours (per day + schema) | ❌ | ✅ |
| Amenities (pet-friendly, woman-owned, LGBTQ+, …) | ❌ | ✅ |
| Currency, price range, gift cards & memberships | ❌ | ✅ |
| **Venue's own website (unclaimed listings)** | ❌ | ✅ |
| **Contact emails / phones / socials** (website crawl) | ❌ | ✅ opt-in |
| Nearby venues (extra discovery) | ❌ | ✅ opt-in |
| Lead score (0–100) per venue | ❌ | ✅ |
| Monitoring — only new venues | ❌ | ✅ |

It captures **both** the claimed, bookable venues (`/a/`) *and* the unclaimed "lite" listings (`/lvp/`) — so a single city + category search returns far more businesses than scrapers that see only one type.

### Use cases

- **Lead generation** — salons, spas and barbershops are high-intent local buyers for booking software, payments, POS, marketing, supplies and insurance. Score them by size and reputation (`reviewsCount`, `serviceCount`, `teamSize`) and reach them by `phone`, `website` or enriched `contactEmails`.
- **Local market & pricing intelligence** — compare service menus and prices (`services[].price`), price ranges and rating distributions across a city or category.
- **Sales territory building** — pull every hair salon / nail bar / medspa in a metro with address, geo and phone for route planning and outreach.
- **Competitor & supply monitoring** — schedule recurring runs to watch a city/category for **newly listed** venues with monitoring mode.
- **Aggregators & directories** — feed apps and marketplaces with structured beauty/wellness venue data, including services and opening hours.

### How to use

1. [Sign up for Apify](https://console.apify.com/sign-up) — the free plan is enough to try this actor.
2. Open the **Fresha Scraper**, choose business types and locations (or paste Fresha URLs), and click **Start**.
3. Watch venues stream into the dataset table.
4. **Export** as JSON, CSV, Excel, XML, or RSS — or pull results via the [Apify API](https://docs.apify.com/api/v2).

### Input

```json
{
    "businessTypes": ["hair-salons", "barbershops", "nail-salons"],
    "locations": ["New York, US", "London, UK"],
    "maxResults": 200,
    "includeVenueDetails": true,
    "includeServices": true,
    "includeReviews": false,
    "enrichContactEmails": true,
    "monitorMode": false
}
```

- **businessTypes** — `hair-salons`, `barbershops`, `nail-salons`, `beauty-salons`, `eyebrows-and-lashes`, `waxing-salons`, `aesthetics` (medspas), `spas`, `massage`, `tattoo-and-piercing`, `gym-and-fitness`, `personal-trainers`, `tanning-studios`, `weight-loss`, `therapy-centers`. Friendly words like `barbers`, `nails`, `medspa`, `gym` are auto-mapped. Each type is combined with every location.
- **locations** — `City, Country` (`London, UK`, `Dubai, AE`), US `City, ST` (`Austin, TX`), an optional neighborhood (`New York, US, Manhattan`), or a raw Fresha geo slug (`us-new-york`). For non-US locations use the country name (e.g. `Toronto, Canada`).
- **startUrls** — direct Fresha venue URLs (`/a/…` or `/lvp/…`) or category/landing URLs (`/lp/en/bt/…`).
- **maxResults / maxVenuesPerSearch** — global and per-search caps.
- **minRating / withPhoneOnly / freshaVerifiedOnly** — filters.
- **includeVenueDetails** *(default true)* — open each venue for phone, services, team, hours, rating distribution and reviews.
- **includeServices** *(default true)* — the categorised service menu with prices, durations and variants.
- **includeReviews** *(default false)* — output review records (type `review`).
- **includeNearbyVenues** *(default false)* — attach nearby venues found on each page.
- **enrichContactEmails** *(default false)* — when a venue links its own website, crawl it for emails, phones and socials.
- **monitorMode** *(default false)* — emit only venues not seen in previous runs.

### Output

One record per venue (`type: "venue"`), plus optional review records (`type: "review"`):

```json
{
    "type": "venue",
    "venueType": "booking",
    "venueId": "2908118",
    "name": "Forbici London",
    "venueUrl": "https://www.fresha.com/a/forbici-london-london-20-montpelier-street-nwlw36bn",
    "businessType": "Hair Salon",
    "rating": 4.9,
    "reviewsCount": 1748,
    "ratingDistribution": { "5": 1644, "4": 54, "3": 22, "2": 11, "1": 17 },
    "isFreshaVerified": true,
    "phone": "+44 7764 821181",
    "street": "20 Montpelier Street",
    "city": "London",
    "area": "Marylebone",
    "postalCode": "SW7 1HD",
    "country": "gb",
    "latitude": 51.52137,
    "longitude": -0.15332,
    "fullAddress": "20 Montpelier Street, London, England",
    "currency": "GBP",
    "priceMin": 10,
    "priceMax": 330,
    "priceRange": "10 - 330 GBP",
    "serviceCount": 188,
    "serviceCategoryCount": 21,
    "services": [
        { "category": "Featured", "items": [
            { "name": "Spray Tan", "price": 35, "currency": "GBP", "formattedPrice": "from £35", "duration": "30 min - 40 min",
              "variants": [{ "name": "Full Body Spray Tan", "price": "£45", "duration": "40 min" }] }
        ] }
    ],
    "teamSize": 4,
    "team": [{ "name": "Tyson", "jobTitle": "Director Stylist", "rating": null }],
    "amenities": ["Pet-friendly", "Woman-owned", "LGBTQ+"],
    "openingHours": { "days": [{ "day": "Monday", "closed": false, "hours": "10:00 AM - 7:00 PM" }], "status": "Open" },
    "hasGiftCards": true,
    "hasMemberships": true,
    "website": null,
    "contactEmails": [],
    "leadScore": 79,
    "searchBusinessType": "hair-salons",
    "searchLocation": "London, UK",
    "scrapedAt": "2026-06-15T12:00:00.000Z"
}
```

Unclaimed "lite" venues (`venueType: "lite"`) skip the bookable service menu but add the venue's **own `website`** (the best email-enrichment target) plus `offeredCategories` with treatment names.

### Automate & schedule

Run this actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** — start runs, fetch datasets, manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[Python](https://docs.apify.com/api/client/python/)** — official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** — run it daily/weekly to track new salons & spas in a city or category; perfect for lead pipelines.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** — trigger downstream actions (CRM import, Slack alert, email sequence) the moment a run finishes.

```js
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/fresha-scraper').call({
    businessTypes: ['hair-salons', 'barbershops'],
    locations: ['Austin, TX'],
    maxResults: 200,
    enrichContactEmails: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} beauty & wellness venues`);
```

### Monitoring mode

Turn on **monitorMode** and the actor remembers every venue id it has returned (in a named key-value store) and emits **only new venues** on the next run. It pairs cleanly with [Schedules](https://docs.apify.com/platform/schedules) — the schedule triggers the run; monitoring decides what's new — so you can watch a city/category for newly listed businesses without conflict or duplicates.

### Integrate with any app

Connect the dataset to 5,000+ apps — no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** — multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** — push new venue leads straight into your CRM.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** — get notified when a monitored search finds new venues.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** — auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** — pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** — trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM-ready JSON. Call this actor from Claude, ChatGPT, or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** — ask your assistant to "find the top-rated hair salons in Miami with their phone numbers and prices" and let it run this scraper for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### More scrapers from scrapesage

Build a complete **local-business lead-gen stack**:

- **[Healthgrades Scraper](https://apify.com/scrapesage/healthgrades-scraper)** — doctors & healthcare providers with reviews and contacts.
- **[WebMD Scraper](https://apify.com/scrapesage/webmd-scraper)** — physicians, insurance and provider leads.
- **[FindLaw Scraper](https://apify.com/scrapesage/findlaw-scraper)** — lawyers, law firms and contact leads.
- **[Insurance Agent Scraper](https://apify.com/scrapesage/insurance-agent-scraper)** — State Farm & Farmers agent leads.
- **[Financial Advisor Scraper](https://apify.com/scrapesage/financial-advisor-scraper)** — FINRA & SEC advisor/broker leads.
- **[Houzz Scraper](https://apify.com/scrapesage/houzz-scraper)** — home-improvement pros, contacts and reviews.
- **[Bark Listing Scraper](https://apify.com/scrapesage/bark-listing-scraper)** — service-provider leads from Bark.
- **[Google Ads Transparency Scraper](https://apify.com/scrapesage/google-ads-transparency-scraper)** — see who's advertising what.

### Tips

- **More venues per city**: each business-type + city landing returns roughly 40–130 venues. To go deeper, add more business types, target specific neighborhoods (`New York, US, Manhattan`), or turn on `includeNearbyVenues`.
- **Best phone coverage**: keep `includeVenueDetails` on — the phone number lives on the venue page, not the listing.
- **Emails**: claimed Fresha venues keep customers on-platform (no website), but unclaimed "lite" listings often link their own site — turn on `enrichContactEmails` to crawl those for emails and socials.
- **Cost control**: filter with `minRating` / `withPhoneOnly` and cap with `maxResults`. Detail, reviews and enrichment are all opt-in.

### FAQ

**How do I scrape salons/spas for a specific city?** Put the city in `locations` (`Austin, TX`, `London, UK`, `Dubai, AE`) and pick `businessTypes`. Each type pairs with each city.

**Which categories are supported?** Hair salons, barbershops, nail salons, beauty salons, brows & lashes, waxing, medspas/aesthetics, spas, massage, tattoo & piercing, gyms & fitness, personal trainers, tanning, weight loss and therapy/wellness centers.

**Where do phone numbers and emails come from?** Phones come from the public Fresha venue page. Emails are never taken from Fresha — with `enrichContactEmails` on, the actor visits a venue's *own* linked website (mostly unclaimed listings) and extracts publicly listed contacts.

**Can I export to Google Sheets, CSV, or Excel?** Yes — one click in the dataset view, or automatically every run via the [Google Drive integration](https://docs.apify.com/platform/integrations/drive).

**How do I get only new venues over time?** Turn on `monitorMode` and create a [Schedule](https://docs.apify.com/platform/schedules); each run emits only venues not seen before.

**A field is null — why?** Some venues genuinely don't publish a price, website or reviews (especially unclaimed "lite" listings). Fields are `null` only when the data doesn't exist, not because the scraper skipped them.

**Is scraping Fresha legal?** This actor collects publicly available data only. You are responsible for using the data in compliance with applicable laws (GDPR/CCPA for personal data) and Fresha's terms.

### Need help?

Open an issue on the actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome — this actor is actively maintained.

# Actor input Schema

## `businessTypes` (type: `array`):

Venue categories: hair-salons, barbershops, nail-salons, beauty-salons, eyebrows-and-lashes, waxing-salons, aesthetics, spas, massage, tattoo-and-piercing, gym-and-fitness, personal-trainers, tanning-studios, weight-loss, therapy-centers. Friendly words (barbers, nails, medspa) auto-map.

## `locations` (type: `array`):

Where to search — `City, Country` (`London, UK`, `Toronto, Canada`, `Dubai, AE`) or US `City, ST` (`Austin, TX`); optional neighborhood (`New York, US, Manhattan`) or a raw geo slug (`us-new-york`). For non-US, use the country name. Empty = the type's global page, or Start-URLs-only.

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

Paste Fresha venue URLs (`https://www.fresha.com/a/...`) or category/landing URLs (`https://www.fresha.com/lp/en/bt/...`). Processed in addition to the business types + locations above.

## `defaultCountry` (type: `string`):

Fallback country code used when a location has no country (e.g. just `Miami`). Two-letter ISO code such as `us`, `gb`, `ca`, `au`, `ae`.

## `maxVenuesPerSearch` (type: `integer`):

Cap the number of venues collected per business-type + location pair. A landing page yields roughly 40-130 venues.

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

Global cap on the total number of venue records emitted in this run, across all searches and Start URLs.

## `minRating` (type: `number`):

Keep only venues with an average rating at or above this value (0 = no filter). Rated 1-5.

## `withPhoneOnly` (type: `boolean`):

Keep only venues that expose a contact phone number (best for cold-call / SMS lead lists). Requires venue details.

## `freshaVerifiedOnly` (type: `boolean`):

Keep only venues with the Fresha-verified badge. Requires venue details.

## `includeVenueDetails` (type: `boolean`):

Visit each venue page to add the deep fields: phone, structured address + geo, star-rating distribution, currency & price range, full service menu with prices & durations, team members, opening hours, amenities, memberships/gift cards and embedded reviews. One extra request per venue.

## `includeServices` (type: `boolean`):

Include the categorised service menu with prices, durations and variants for each venue. Requires venue details.

## `maxServiceItems` (type: `integer`):

Cap the number of individual services kept per venue to keep records lean (large venues list 100+).

## `includeReviews` (type: `boolean`):

Also output review records (type `review`) shown on each venue page — star rating, text (when present), author, date and the owner's reply. Requires venue details.

## `maxReviewsPerVenue` (type: `integer`):

How many reviews to emit per venue when 'Include reviews' is on (venue pages expose the most recent batch).

## `includeNearbyVenues` (type: `boolean`):

Attach a list of nearby venues (name, rating, type, area) found on each venue page — useful for discovering more businesses in the same area. Requires venue details.

## `enrichContactEmails` (type: `boolean`):

Opt-in lead enrichment: when a venue links its own website (common for unclaimed 'lite' listings), visit it (home + a contact/about page) and extract emails, phone numbers and social links. Only runs when a website exists. Requires venue details.

## `deduplicateVenues` (type: `boolean`):

Emit each venue only once per run (keyed by venue id / URL), even if it appears across multiple business types or locations.

## `monitorMode` (type: `boolean`):

Remember venues already returned and emit ONLY venues not seen in previous runs. Pairs with Apify Schedules to track newly listed salons/spas in an area over time.

## `monitorStoreName` (type: `string`):

Named key-value store that holds the 'already seen' venue ids for monitoring mode. Use a different name per tracked search to keep their histories separate.

## `maxConcurrency` (type: `integer`):

Maximum parallel requests. Lower it if you hit rate limits on very large runs.

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

Proxy settings. Fresha serves clean pages globally, so the default Apify proxy is enough; switch to residential for very large or high-frequency runs.

## Actor input object example

```json
{
  "businessTypes": [
    "hair-salons"
  ],
  "locations": [
    "New York, US"
  ],
  "defaultCountry": "us",
  "maxVenuesPerSearch": 60,
  "maxResults": 100,
  "minRating": 0,
  "withPhoneOnly": false,
  "freshaVerifiedOnly": false,
  "includeVenueDetails": true,
  "includeServices": true,
  "maxServiceItems": 100,
  "includeReviews": false,
  "maxReviewsPerVenue": 20,
  "includeNearbyVenues": false,
  "enrichContactEmails": false,
  "deduplicateVenues": true,
  "monitorMode": false,
  "monitorStoreName": "fresha-monitor",
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

All scraped records in the default dataset. Venue rows carry the full business profile, contact, ratings, services, team, hours and lead score; review rows carry their own fields.

# 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 = {
    "businessTypes": [
        "hair-salons"
    ],
    "locations": [
        "New York, US"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/fresha-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 = {
    "businessTypes": ["hair-salons"],
    "locations": ["New York, US"],
}

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/fresha-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "businessTypes": [
    "hair-salons"
  ],
  "locations": [
    "New York, US"
  ]
}' |
apify call scrapesage/fresha-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=scrapesage/fresha-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/JLV2o6iq5lAYvIK0z/builds/NXjnXoY2V8Y2DR0h4/openapi.json
