# Hot Pepper Beauty Scraper - Salons, Prices & Reviews (`abotapi/beauty-hotpepper-jp-scraper`) Actor

Scrape Japanese hair, nail, relaxation and esthetic salons from Hot Pepper Beauty (beauty.hotpepper.jp). Search by area or keyword, or paste URLs. Returns address, phone, coordinates, rating, reviews count, hours, payment methods, features, coupons with prices and the latest review.

- **URL**: https://apify.com/abotapi/beauty-hotpepper-jp-scraper.md
- **Developed by:** [Abot API](https://apify.com/abotapi) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 salon results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Hot Pepper Beauty Salon Scraper: Salons, Ratings, Coupons

Hot Pepper Beauty Salon Scraper turns Japan's largest salon directory, Hot Pepper Beauty (beauty.hotpepper.jp), into structured data. Search hair, nail, relaxation and esthetic salons by area or keyword, or paste salon and list links. Every salon comes back with address, phone, coordinates, rating, review count, opening hours, payment methods, features, coupons with prices and the latest review with the salon's reply. Optionally, every salon also carries its customer reviews, newest first, each with its scores and the salon's public reply. Export to JSON, CSV or Excel, or read the results through the API.

### Why This Scraper?

- **Four salon families.** Hair, nail and eyelash, relaxation and esthetic salons from one actor.
- **Search the way you think.** Type an area name such as 新宿, an area code, a whole region, or a keyword such as a station or style.
- **Paste links instead.** Salon pages, sub-pages (coupons, reviews, styles) and area list pages all work.
- **Rich records.** Around 60 fields per salon, including coordinates, payment methods, average spend and customer mix.
- **Customer reviews, nested.** Switch on reviews and each salon row carries a `reviews` list (paginated for you, de-duplicated, with the salon's replies and the four aspect scores). No extra dataset rows to join.
- **Coupons with prices.** Every listed coupon with title, price and labels, ready for price monitoring.
- **Recurring monitoring and cost control.** Incremental mode returns only new or changed salons (unchanged ones are not billed), Max items is the one cap, and a detail switch gives lighter summary-only runs.

### Use Cases

- **Market researchers:** map salon density, price levels and ratings across Japanese areas.
- **Suppliers and sales teams:** build lead lists of salons with phone numbers and addresses by neighbourhood.
- **Price analysts:** track coupon prices and cut prices over time with scheduled runs.
- **Franchise and location planners:** compare competitor salons near a candidate site using coordinates and ratings.
- **Review analysts:** follow review counts and scores per salon.

### Data You Get

> Sample shape: values are illustrative placeholders, not from a live record.

| Field | Example |
| --- | --- |
| `salonId` | H000000000 |
| `name`, `salonNameKana` | Example Salon (Example), and the kana reading line under the title |
| `serviceType` | hair |
| `url` | https://beauty.hotpepper.jp/slnH000000000/ |
| `rating` | 4.5 |
| `reviewCount` | 100 |
| `phone` | +81-00-0000-0000 |
| `address` | Tokyo, Shinjuku-ku, 1-1-1 |
| `prefecture` | 東京都 |
| `areaName` | 新宿・高田馬場・代々木 |
| `latitude`, `longitude` | 35.69, 139.7 |
| `nearestStation` | JR Shinjuku Station 3 min on foot |
| `businessHours` | 10:00-21:00 |
| `paymentMethods` | Visa, Mastercard |
| `cutPrice` | ¥3,000～ |
| `priceMin`, `priceMax` | 3000, 5000 |
| `city`, `prefectureEn` | 新宿区, Tokyo |
| `website` | The salon's own site, as plain text |
| `customerGender` | Share of women, men and others, in percent |
| `customerAgeWomen` | Share by age band (under20, 20s, 30s, 40s, 50plus) |
| `averageCostFirstVisit` | ¥8,000～¥8,999 |
| `seatCount`, `staffCount` | 8, 10 |
| `features` | Open after 7 pm, Drinks served |
| `coupons` | Coupon titles with prices and labels |
| `latestReview`, `reviews` | The latest review with the salon's reply; with reviews on, the nested customer reviews and `reviewsDelivered` (see Customer reviews below) |

### How to Use

1. Pick a **mode**: `search` (areas or keywords) or `url` (paste links).
2. Fill in the fields for that mode, and choose whether to open every salon page for full detail.
3. Set **Max items** to control run size and cost, then click **Start**.
4. Download the dataset as JSON, CSV or Excel, or read it through the API.

**Hair salons in Shinjuku:**

```json
{
  "mode": "search",
  "areas": ["新宿"],
  "maxItems": 20
}
```

**Nail salons in an area, summary only:**

```json
{
  "mode": "search",
  "areas": ["渋谷"],
  "serviceType": "nail",
  "fetchDetails": false,
  "maxItems": 50
}
```

**One salon page and an area list:**

```json
{
  "mode": "url",
  "urls": [
    "https://beauty.hotpepper.jp/slnH000000000/",
    "https://beauty.hotpepper.jp/svcSA/macAA/salon/"
  ],
  "maxItems": 30
}
```

#### Run it from your code

Python:

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("abotapi/beauty-hotpepper-jp-scraper").call(run_input={"mode": "search", "areas": ["新宿"], "maxItems": 20})
for salon in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(salon["name"], salon["rating"], salon["reviewCount"])
```

JavaScript:

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

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('abotapi/beauty-hotpepper-jp-scraper').call({ mode: 'search', areas: ['新宿'], maxItems: 20 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the **Integrations** tab.

#### Areas and keywords

Area names are matched against the site's own area list, so a short name such as 新宿 or a romaji spelling such as shinjuku finds the matching area. Area codes work too (macAA, macAA|新宿), and so do sub-area codes such as macAA/sacX001. A region name such as 関東 expands to every area in that region, which can be a large run, so keep Max items in mind. A name that matches nothing is reported in the log, and the run stops with a clear message if none of your areas matched. Use **Prefectures** to keep only salons in chosen prefectures. Keyword searches cover hair salons.

#### Links you can paste

In URL mode every one of these works: an area list page (also its area top page, a sub-area page, a page-2 list and the nail, relax and esthe versions), a salon page or one of its coupon, review or style pages, and a keyword search page. Whole-region pages, the home page, catalog, ranking and recruiting pages are skipped with a warning instead of producing wrong rows.

#### Customer reviews

Turn on **Add customer reviews to each salon** (`includeReviews`) to get a `reviews` list on every salon row. It needs **Fetch salon detail pages** switched on, and salons with no reviews cost no extra request. **Max reviews per salon** (`maxReviewsPerSalon`, default 30, at most 300) limits how many reviews each salon carries; the site shows 30 reviews per page and the actor follows its pages until your limit or the last page.

Each review carries:

- `date` (the day it was posted, YYYY-MM-DD), `rating` (the overall score, 1 to 5) and `ratings` (atmosphere, service, technique, menuPrice, each 1 to 5);
- `text`, the review as written, and `menu` / `treatments`, the coupon or menu the customer booked;
- `salonReply`, the salon's public reply to that review (empty when there is none);
- `salonPick`, true for the review the salon pinned at the top of the first page;
- `reviewKey`, a stable key for the review.

Newest reviews come first, except the salon's pinned review, which sits at the top of its first page. The site shows no review id, so `reviewKey` is a fingerprint built from the posting date, the overall and aspect scores and the full text; the same review always gets the same key, and a review repeated across pages is returned once. Two reviews with the same date, scores and text would count as one.

**What is left out on purpose:** reviewer names, profile links and the age, gender and job details the site shows beside a review. A reviewer's nickname is also removed from the salon's reply. Review text and salon replies are published as written, so they can still contain whatever the writer chose to put in them.

**How the score is calculated.** The official salon `rating` and the aspect averages on the site are calculated from the reviews posted in the preceding year, not from every review ever written (see the site's guide at https://beauty.hotpepper.jp/doc/review_guide/review_average_point.html). `reviewCount` counts every review, so a salon can have many reviews and a score that moves as old ones age out. The `reviews` list is not limited to that year, so you can recompute any window yourself.

**Recurring runs.** Reviews are not compared in incremental mode and are not stored in the saved state. A salon turns UPDATED when its `reviewCount` or `rating` changes (a new review changes the count), and `changedFields` then names those fields; the review list itself never appears there. Reviews are billed per review returned on a row that is returned.

#### Resume and recurring updates

- **Resume** (`resumeFromRunId`) continues one interrupted run: paste its run or dataset ID and the actor skips every salon already collected there.
- **Incremental mode** (`incrementalMode`) is for scheduled runs over the same scope. Each salon is classified `NEW`, `UPDATED` (with `changedFields`) or `REAPPEARED`. Unchanged salons are not returned or billed unless you turn on `emitUnchanged`. Every returned field is compared, including rating and review counts (the nested `reviews` list is not, see Customer reviews); add fields you consider noise (for example `rating` or `coupons`) to `ignoreFieldsForChanges`. With `emitExpired`, salons that were listed before and are gone are returned as `EXPIRED`, but only after a run that walked every tracked area or keyword to its last page (never when Max items or Max list pages cut it short, or when Resume was used), and never more than Max items allows. `stateKey` names or shares the stored state. State is kept per search setup: areas, keywords, links, category, detail pages, minimum reviews, minimum rating and prefectures.

### Send results into your apps (MCP connectors)

Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step **after** the scrape: the Apify dataset is never changed.

**What gets written to the connector:** a condensed, human-readable **summary** of each record, not the full JSON. Each item becomes one entry with a **title** and its key fields flattened to plain text. The **complete record always stays in the Apify dataset**.

1. Authorize a connector once under **Apify → Settings → Integrations** (Notion, Linear, Airtable, or Apify).
2. Select it in the **"Pipe results into your apps"** input field. (If the picker is empty, you haven't authorized a connector yet.)
3. For **Notion**, also set `notionParentPageUrl` to the page where items should be created.

The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.

### Input Parameters

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `mode` | string | search | Search builds salon lists from areas or keywords. URL mode takes salon pages or area list pages you paste. Fields in the other mode's section are ignored. |
| `areas` | array | - | Area names in Japanese such as 新宿 or 渋谷, or in romaji such as shinjuku, an area code such as macAA (optionally with its name, macAA|新宿), a sub-area code such as macAA/sacX001, a region name such as 関東 (expands to every area in the region), or an area list link. Ignored in URL mode. |
| `keywords` | array | - | Free-text salon search, for example a station, style or salon name. Each keyword is its own search over hair salons. Ignored in URL mode. |
| `serviceType` | string | hair | Which salon family to list for the chosen areas. |
| `minReviewCount` | integer | - | Skip salons with fewer reviews than this (applied to the review count shown on the list page). |
| `minRating` | number | - | Skip salons whose average review score is below this value (1 to 5). Setting it turns on salon detail pages because the score comes from there. |
| `prefectures` | array | - | Keep only salons located in these prefectures, for example 東京都, 神奈川県 or Tokyo. Combine with a region name such as 関東 in Areas. Setting it turns on salon pages because the address comes from there. Applies in search and URL mode. |
| `urls` | array | \["https://beauty.hotpepper.jp/svcSA/macAA/salon/"] | Paste any of these links: an area list (including its area top, sub-area and page-2 forms, and the nail, relax and esthe versions), a salon page or one of its coupon, review or style sub-pages, or a keyword search page. Area and search lists are walked page by page; each salon link returns one record. Whole-region pages, the home page, catalog and ranking pages are skipped with a warning. Filter fields are ignored in URL mode. |
| `fetchDetails` | boolean | true | Open every salon page for full data: phone, address, coordinates, rating, hours, payment methods, features, coupons and the latest review. Off returns only the list-page summary. |
| `includeReviews` | boolean | false | Adds the salon's customer reviews to each row as a list, newest first: date, overall score, the four scores (atmosphere, service, technique, menu and price), the review text, the menu booked and the salon's public reply where there is one. Reviewer names and profiles are never included. Needs 'Fetch salon detail pages' switched on. Each review is a separate paid event. |
| `maxReviewsPerSalon` | integer | 30 | How many reviews to collect for each salon when reviews are on (30 reviews per page of the site, at most 300). Reviews are billed per review returned, so this is also the most each salon can add to the bill. |
| `maxPages` | integer | - | Optional limit on list pages walked per area or keyword. Empty or 0 means unlimited. This does NOT cap the output; Max items is the cap. |
| `maxItems` | integer | 20 | Maximum salons to return in total. 0 means unlimited. |
| `proxy` | object | {"useApifyProxy": true} | Proxy settings. The default datacenter connection works on every plan. Residential is recommended for the most reliable results, especially on large or frequent runs. If the selected connection is unavailable to your plan or is refused, the run moves on to a backup connection automatically; residential traffic from that automatic step is billed to your Apify plan. |
| `resumeFromRunId` | string | - | Run ID (or dataset ID) of a previous run of this Actor. Salons already collected there are skipped, so this run returns only new ones. Leave empty for a normal run. |
| `incrementalMode` | boolean | false | Turn this on for daily or recurring monitoring. A salon is UPDATED when any returned detail changes, including rating and review counts; add fields you consider noise to Ignore fields below. The first run returns all matching salons as NEW; later runs return only NEW, UPDATED and REAPPEARED salons, and unchanged ones are neither returned nor billed unless Emit unchanged is on. State is kept separately for each search setup (areas, keywords, links, category, detail pages, minimum reviews and rating); use State key to name or share one monitoring campaign. |
| `stateKey` | string | - | Optional name for an incremental monitoring campaign. Leave empty to derive it from the search setup. |
| `emitUnchanged` | boolean | false | Off by default. Turn on to also return salons that have not changed since the last run, marked UNCHANGED. This returns, and bills, rows you already have, so leave it off unless you want the full snapshot every run. |
| `emitExpired` | boolean | false | Off by default. Turn on to also return salons that were present in an earlier run but are no longer listed, marked EXPIRED. Only produced after a run that walked every tracked area or keyword list to its last page, so never when Max items or Max list pages cut the run short, when Resume was used, or in URL mode with single salon links. This returns, and bills, extra rows, so leave it off unless you need expiry tracking. |
| `ignoreFieldsForChanges` | array | - | Field names that must never make a salon UPDATED, for example rating, reviewCount or coupons. They are still returned in every row. Nothing is ignored by default except run bookkeeping (retrievedAt, position, sourceListUrl) and the nested customer reviews, so a new review alone does not make a salon UPDATED; it still does when the review count or rating changes. Used only in incremental mode. |
| `mcpConnectors` | array | - | Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON, the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com). |
| `notionParentPageUrl` | string | - | URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors. |
| `maxNotifyListings` | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |

### Output Example

> Sample shape: values are illustrative placeholders, not from a live record.

**One salon record:**

```json
{
  "salonId": "H000000000",
  "name": "Example Salon (Example)",
  "salonName": "Example Salon Shinjuku / Color / Cut",
  "schemaType": "HairSalon",
  "serviceType": "hair",
  "url": "https://beauty.hotpepper.jp/slnH000000000/",
  "rating": 4.5,
  "reviewCount": 100,
  "blogCount": 10,
  "couponCount": 8,
  "phone": "+81-00-0000-0000",
  "address": "Tokyo, Shinjuku-ku, 1-1-1",
  "prefecture": "東京都",
  "prefectureCode": "13",
  "regionCode": "SA",
  "regionName": "関東",
  "areaCode": "macAA",
  "areaName": "新宿・高田馬場・代々木",
  "latitude": 35.69,
  "longitude": 139.7,
  "nearestStation": "JR Shinjuku Station 3 min on foot",
  "businessHours": "10:00-21:00",
  "closedDays": "Open every day",
  "paymentMethods": [
    "Visa",
    "Mastercard"
  ],
  "cutPrice": "¥3,000～",
  "priceMin": 3000,
  "priceRange": "¥3,000～",
  "averageCostFirstVisit": "¥8,000～¥8,999",
  "averageCostRepeat": "¥7,000～¥7,999",
  "seatCount": 8,
  "staffCount": 10,
  "hasOnlineBooking": true,
  "features": [
    "Open after 7 pm",
    "Drinks served"
  ],
  "coupons": [
    {
      "couponId": "CP00000000000000",
      "title": "Cut and color",
      "price": 6500,
      "labels": [
        "New"
      ]
    }
  ],
  "latestReview": {
    "date": "2026/1/1",
    "ratings": {
      "総合": 5
    },
    "text": "Sample review text.",
    "salonReply": null
  },
  "salonNameKana": "Example Salon Shinjuku",
  "reviews": [
    {
      "reviewKey": "r0000000000000000",
      "date": "2026-01-01",
      "rating": 5,
      "ratings": {
        "atmosphere": 5,
        "service": 5,
        "technique": 5,
        "menuPrice": 4
      },
      "text": "Sample review text.",
      "menu": "Cut and color",
      "treatments": [
        "Cut",
        "Color"
      ],
      "salonReply": "Sample reply text.",
      "salonPick": false
    }
  ],
  "reviewsDelivered": 1,
  "detailFetched": true,
  "retrievedAt": "2026-01-01T00:00:00Z"
}
```

### Plan Requirement

The actor runs on the datacenter Apify proxy by default, which works on every plan. Residential is recommended for the most reliable results, especially on large or frequent runs; select it in the proxy setting. If the selected connection is refused or keeps failing, the run steps up to Apify residential automatically (billed to your Apify plan) and steps back down once the cheaper connection reads reliably again. Apify free plans do not include residential proxies: on a free plan the run logs a notice and continues on a backup connection, and some pages may still be unavailable. To get residential access, upgrade at https://apify.com/pricing or supply your own proxy URLs. Paid Apify plans get lower tiered event rates.

What you may see in the run log:

- **Notice, connection unavailable:** "The selected connection is unavailable to this run. Apify free plans do not include residential proxies. Continuing on a backup connection; some pages may still be unavailable."
- **Info:** "Served over the backup connection (the default connection was unavailable)."
- **Failure, proxy refused:** the run ends with "The proxy connection was refused for this account, so no page could be read." and asks for a paid plan or valid proxy URLs.
- **Failure, free plan:** "No results: residential proxies are unavailable on this run, and the backup connection could not load the requested Hot Pepper Beauty pages."
- **Failure, other:** "Could not load any results page (the requests failed), so nothing was collected. This is a connection problem, not an empty search."

### FAQ

#### How much does it cost?

Pay per event. The current rates are shown on the **Pricing** tab. The events and when each one is charged:

| Event | When it is charged |
| --- | --- |
| Result (`apify-default-dataset-item`) | once for each salon pushed to the dataset |
| Detail enrichment (`detail-enrichment`) | once per returned salon whose full detail page was added |
| Review enrichment (`review-enrichment`) | once per customer review returned on a salon row, only when reviews are switched on |
| Actor Start (`apify-actor-start`) | once per run, per GB of memory |

Unchanged salons in incremental mode are not billed. The latest review is part of the salon page and has no separate charge. Nested reviews are charged per review actually returned, so **Max reviews per salon** bounds what each salon can add. Use **Max items** to cap the cost of any run.

#### Is it legal to scrape Hot Pepper Beauty?

This actor collects only publicly available salon information. You are responsible for how you use it: follow the site's terms and the laws that apply to you, including Japanese data protection rules, and get legal advice if you plan commercial redistribution.

#### Can I get only new or changed salons on a schedule?

Yes. Schedule the actor from the **Schedules** tab and turn on **Incremental mode**.

#### Why is the rating empty on some rows?

The rating comes from the salon page. Turn on **Fetch salon detail pages**, or the row carries only the list-page summary. Salons with no reviews in the preceding year have no score. A salon's `priceMax` is empty when the site shows an open-ended price (for example from 3,000 yen).

#### Why did my run fail instead of returning an empty dataset?

If the site cannot be read at all, the run stops with a clear message so "no salons matched" is never confused with "nothing could be read". Run it again in a few minutes.

#### Can I use it with AI agents or MCP?

Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.

### 🔗 More scrapers you might like

Pair this actor with these related scrapers from the same team:

<table>
<tr><td>🧩 <a href="https://apify.com/abotapi/booksy-beauty-business-scraper"><b>Booksy Scraper</b></a><br>Scrape Booksy beauty businesses across the US, UK and Poland by category, location or...</td><td>🧩 <a href="https://apify.com/abotapi/fresha-salon-spa-scraper"><b>Fresha Scraper</b></a><br>Scrape Fresha salon and spa listings: business profiles, service menus with prices and...</td></tr>
<tr><td>🧩 <a href="https://apify.com/abotapi/mistore-jp-scraper"><b>Isetan Mitsukoshi</b></a><br>Scrape the Isetan Mitsukoshi department store online shop (mistore.jp). Search by keyword...</td><td>🧩 <a href="https://apify.com/abotapi/suumo-jp-scraper"><b>Suumo.jp Scraper</b></a><br>Scrape Suumo, Japan's largest property portal: rental rooms with rent, management fees...</td></tr>
<tr><td>👗 <a href="https://apify.com/abotapi/zozotown-scraper"><b>ZOZOTOWN</b></a><br>Scrape ZOZOTOWN (zozo.jp), Japan's largest fashion marketplace: name, brand, JPY price...</td><td>🛒 <a href="https://apify.com/abotapi/nitori-net-jp-scraper"><b>Nitori Japan Furniture &amp; Home Goods Scraper</b></a><br>Scrape Nitori Japan (nitori-net.jp) furniture and home goods by keyword, category or...</td></tr>
</table>

👉 [Browse all abotapi scrapers](https://apify.com/abotapi)

### 💬 Support

- 🐞 **Found a bug or a missing field?** Open a ticket on the [Issues tab](https://apify.com/abotapi/beauty-hotpepper-jp-scraper/issues/open). We usually reply within hours.
- 🛠️ **Need another site, extra fields or a private build?** Email <contact@abotapi.com>.
- ⭐ **Enjoying it?** A quick review on the actor page helps other users find it.

# Actor input Schema

## `mode` (type: `string`):

Search builds salon lists from areas or keywords. URL mode takes salon pages or area list pages you paste. Fields in the other mode's section are ignored.

## `areas` (type: `array`):

Area names in Japanese such as 新宿 or 渋谷, or in romaji such as shinjuku, an area code such as macAA (optionally with its name, macAA|新宿), a sub-area code such as macAA/sacX001, a region name such as 関東 (expands to every area in the region), or an area list link. Ignored in URL mode.

## `keywords` (type: `array`):

Free-text salon search, for example a station, style or salon name. Each keyword is its own search over hair salons. Ignored in URL mode.

## `serviceType` (type: `string`):

Which salon family to list for the chosen areas.

## `minReviewCount` (type: `integer`):

Skip salons with fewer reviews than this (applied to the review count shown on the list page).

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

Skip salons whose average review score is below this value (1 to 5). Setting it turns on salon detail pages because the score comes from there.

## `prefectures` (type: `array`):

Keep only salons located in these prefectures, for example 東京都, 神奈川県 or Tokyo. Combine with a region name such as 関東 in Areas. Setting it turns on salon pages because the address comes from there. Applies in search and URL mode.

## `urls` (type: `array`):

Paste any of these links: an area list (including its area top, sub-area and page-2 forms, and the nail, relax and esthe versions), a salon page or one of its coupon, review or style sub-pages, or a keyword search page. Area and search lists are walked page by page; each salon link returns one record. Whole-region pages, the home page, catalog and ranking pages are skipped with a warning. Filter fields are ignored in URL mode.

## `fetchDetails` (type: `boolean`):

Open every salon page for full data: phone, address, coordinates, rating, hours, payment methods, features, coupons and the latest review. Off returns only the list-page summary.

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

Adds the salon's customer reviews to each row as a list, newest first: date, overall score, the four scores (atmosphere, service, technique, menu and price), the review text, the menu booked and the salon's public reply where there is one. Reviewer names and profiles are never included. Needs 'Fetch salon detail pages' switched on. Each review is a separate paid event.

## `maxReviewsPerSalon` (type: `integer`):

How many reviews to collect for each salon when reviews are on (30 reviews per page of the site). Reviews are billed per review returned, so this is also the most each salon can add to the bill.

## `maxPages` (type: `integer`):

Optional limit on list pages walked per area or keyword. Empty or 0 means unlimited. This does NOT cap the output; Max items is the cap.

## `maxItems` (type: `integer`):

Maximum salons to return in total. 0 means unlimited.

## `proxy` (type: `object`):

Proxy settings. The default datacenter connection works on every plan. Residential is recommended for the most reliable results, especially on large or frequent runs. If the selected connection is unavailable to your plan or is refused, the run moves on to a backup connection automatically; residential traffic from that automatic step is billed to your Apify plan.

## `resumeFromRunId` (type: `string`):

Run ID (or dataset ID) of a previous run of this Actor. Salons already collected there are skipped, so this run returns only new ones. Leave empty for a normal run.

## `incrementalMode` (type: `boolean`):

Turn this on for daily or recurring monitoring. A salon is UPDATED when any returned detail changes, including rating and review counts; add fields you consider noise to Ignore fields below. The first run returns all matching salons as NEW; later runs return only NEW, UPDATED and REAPPEARED salons, and unchanged ones are neither returned nor billed unless Emit unchanged is on. State is kept separately for each search setup (areas, keywords, links, category, detail pages, minimum reviews and rating); use State key to name or share one monitoring campaign.

## `stateKey` (type: `string`):

Optional name for an incremental monitoring campaign. Leave empty to derive it from the search setup.

## `emitUnchanged` (type: `boolean`):

Off by default. Turn on to also return salons that have not changed since the last run, marked UNCHANGED. This returns, and bills, rows you already have, so leave it off unless you want the full snapshot every run.

## `emitExpired` (type: `boolean`):

Off by default. Turn on to also return salons that were present in an earlier run but are no longer listed, marked EXPIRED. Only produced after a run that walked every tracked area or keyword list to its last page, so never when Max items or Max list pages cut the run short, when Resume was used, or in URL mode with single salon links. This returns, and bills, extra rows, so leave it off unless you need expiry tracking.

## `ignoreFieldsForChanges` (type: `array`):

Field names that must never make a salon UPDATED, for example rating, reviewCount or coupons. They are still returned in every row. Nothing is ignored by default except run bookkeeping (retrievedAt, position, sourceListUrl) and the nested customer reviews, so a new review alone does not make a salon UPDATED; it still does when the review count or rating changes. Used only in incremental mode.

## `mcpConnectors` (type: `array`):

Optionally send the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. Authorize a connector once under Apify → Settings → Integrations, then select it here. The connector receives a condensed, human-readable summary per item (title + key fields), not the full JSON, the complete record stays in the dataset. Leave empty to skip. Supported: Notion (https://mcp.notion.com/mcp), Linear (https://mcp.linear.app/sse), Airtable (https://mcp.airtable.com/mcp), Apify (https://mcp.apify.com).

## `notionParentPageUrl` (type: `string`):

URL (or id) of the Notion page under which item pages are created. Required to enable the Notion export; ignored by other connectors.

## `maxNotifyListings` (type: `integer`):

Cap on items written to each connector per run. Does not affect the dataset.

## Actor input object example

```json
{
  "mode": "search",
  "areas": [
    "新宿"
  ],
  "serviceType": "hair",
  "urls": [
    "https://beauty.hotpepper.jp/svcSA/macAA/salon/",
    "https://beauty.hotpepper.jp/svcSA/macAA/",
    "https://beauty.hotpepper.jp/svcSA/macAA/salon/sacX001/",
    "https://beauty.hotpepper.jp/svcSA/macAA/salon/PN2.html?searchGender=ALL&sortType=popular",
    "https://beauty.hotpepper.jp/nail/svcSA/macAA/salon/",
    "https://beauty.hotpepper.jp/slnH000145984/",
    "https://beauty.hotpepper.jp/slnH000145984/coupon/",
    "https://beauty.hotpepper.jp/CSP/bt/salonSearch/search/?freeword=%E6%B8%8B%E8%B0%B7&searchGender=ALL&sortType=popular"
  ],
  "fetchDetails": true,
  "includeReviews": false,
  "maxReviewsPerSalon": 30,
  "maxItems": 20,
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false,
  "maxNotifyListings": 50
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

# 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 = {
    "mode": "search",
    "areas": [
        "新宿"
    ],
    "urls": [
        "https://beauty.hotpepper.jp/svcSA/macAA/salon/",
        "https://beauty.hotpepper.jp/svcSA/macAA/",
        "https://beauty.hotpepper.jp/svcSA/macAA/salon/sacX001/",
        "https://beauty.hotpepper.jp/svcSA/macAA/salon/PN2.html?searchGender=ALL&sortType=popular",
        "https://beauty.hotpepper.jp/nail/svcSA/macAA/salon/",
        "https://beauty.hotpepper.jp/slnH000145984/",
        "https://beauty.hotpepper.jp/slnH000145984/coupon/",
        "https://beauty.hotpepper.jp/CSP/bt/salonSearch/search/?freeword=%E6%B8%8B%E8%B0%B7&searchGender=ALL&sortType=popular"
    ],
    "includeReviews": false,
    "maxReviewsPerSalon": 30,
    "maxItems": 20,
    "proxy": {
        "useApifyProxy": true
    },
    "incrementalMode": false,
    "emitUnchanged": false,
    "emitExpired": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("abotapi/beauty-hotpepper-jp-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 = {
    "mode": "search",
    "areas": ["新宿"],
    "urls": [
        "https://beauty.hotpepper.jp/svcSA/macAA/salon/",
        "https://beauty.hotpepper.jp/svcSA/macAA/",
        "https://beauty.hotpepper.jp/svcSA/macAA/salon/sacX001/",
        "https://beauty.hotpepper.jp/svcSA/macAA/salon/PN2.html?searchGender=ALL&sortType=popular",
        "https://beauty.hotpepper.jp/nail/svcSA/macAA/salon/",
        "https://beauty.hotpepper.jp/slnH000145984/",
        "https://beauty.hotpepper.jp/slnH000145984/coupon/",
        "https://beauty.hotpepper.jp/CSP/bt/salonSearch/search/?freeword=%E6%B8%8B%E8%B0%B7&searchGender=ALL&sortType=popular",
    ],
    "includeReviews": False,
    "maxReviewsPerSalon": 30,
    "maxItems": 20,
    "proxy": { "useApifyProxy": True },
    "incrementalMode": False,
    "emitUnchanged": False,
    "emitExpired": False,
}

# Run the Actor and wait for it to finish
run = client.actor("abotapi/beauty-hotpepper-jp-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 '{
  "mode": "search",
  "areas": [
    "新宿"
  ],
  "urls": [
    "https://beauty.hotpepper.jp/svcSA/macAA/salon/",
    "https://beauty.hotpepper.jp/svcSA/macAA/",
    "https://beauty.hotpepper.jp/svcSA/macAA/salon/sacX001/",
    "https://beauty.hotpepper.jp/svcSA/macAA/salon/PN2.html?searchGender=ALL&sortType=popular",
    "https://beauty.hotpepper.jp/nail/svcSA/macAA/salon/",
    "https://beauty.hotpepper.jp/slnH000145984/",
    "https://beauty.hotpepper.jp/slnH000145984/coupon/",
    "https://beauty.hotpepper.jp/CSP/bt/salonSearch/search/?freeword=%E6%B8%8B%E8%B0%B7&searchGender=ALL&sortType=popular"
  ],
  "includeReviews": false,
  "maxReviewsPerSalon": 30,
  "maxItems": 20,
  "proxy": {
    "useApifyProxy": true
  },
  "incrementalMode": false,
  "emitUnchanged": false,
  "emitExpired": false
}' |
apify call abotapi/beauty-hotpepper-jp-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,abotapi/beauty-hotpepper-jp-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/PgHvHb23uIHXa6mK6/builds/ru6mpJsUFsrISnJ05/openapi.json
