# WhatClinic.com Clinic Scraper (`haketa/whatclinic-scraper`) Actor

WhatClinic scraper & API: find clinics and healthcare providers by treatment and location and export clinic name, treatments, prices, rating and reviews, address, phone and website. Healthcare lead generation and medical market data — fast, no login.

- **URL**: https://apify.com/haketa/whatclinic-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Automation, Developer tools, Lead generation
- **Stats:** 13 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 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?

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

## WhatClinic.com Clinic Scraper — Global Medical & Dental Clinic Directory Data Extractor

> **The most complete WhatClinic.com data extraction tool on Apify.** Pull structured clinic listings, ServiceScores, patient reviews, treatment prices, awards, contact details and full profiles from the world's largest healthcare directory — **120,000+ clinics across 160+ countries** — and turn medical-tourism, dental, cosmetic, fertility and eye-surgery data into ready-to-use JSON for sourcing, comparison, pricing intelligence and lead generation.

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue)](https://apify.com/haketa/whatclinic-scraper)
[![Live Data](https://img.shields.io/badge/Data-Live%20at%20Run%20Time-orange)]()
[![Engine](https://img.shields.io/badge/Engine-Playwright%20%2B%20Chrome-green)]()
[![Coverage](https://img.shields.io/badge/Coverage-160%2B%20Countries-purple)]()
[![Categories](https://img.shields.io/badge/Categories-8%20Treatment%20Verticals-teal)]()
[![Pay Per Event](https://img.shields.io/badge/Pricing-Pay%20Per%20Event-yellow)]()
[![No Auth](https://img.shields.io/badge/Authentication-None%20Required-success)]()
[![Domain](https://img.shields.io/badge/Source-whatclinic.com-red)]()

***

### What This Actor Does

The **WhatClinic.com Clinic Scraper** is a production-ready Apify Actor that extracts structured clinic data from **[WhatClinic.com](https://www.whatclinic.com/)** — the world's largest medical and dental treatment directory. WhatClinic indexes **120,000+ clinics in 160+ countries**, with patient reviews, proprietary ServiceScores, starting prices, treatment menus and verified business profiles spanning eight major treatment verticals.

In a single run, the actor walks WhatClinic's category × country search pages (with optional drill-downs into city, province and individual clinic profiles), normalizes the markup into a flat JSON schema, parses multi-currency prices, and pushes ready-to-use records into the Apify dataset — so you can stop reverse-engineering listing HTML and start building dashboards, lead lists, price-comparison engines and medical-tourism recommendation flows.

A typical record covers:

- **Clinic identity** — name, profile URL, country, city, district, full street address
- **Reputation signals** — proprietary ServiceScore (0–10), score label (Outstanding / Excellent / Very Good / Good), interaction count, patient review count, average rating, awards (Customer Service Award, Global Patients Award, Quality Award)
- **Treatment & pricing** — starting price (`From €1,800`), parsed currency (`EUR`), numeric price (`1800`), treatment menu and per-treatment price list
- **Operational data** — phone, opening hours (when scraped from detail pages), staff/specialist names, gallery photos, long-form description
- **Catalog metadata** — category vertical (Dental, Hair Loss, Cosmetic Surgery, Eye Surgery, Fertility, Physiotherapy, Skin Care, Weight Loss), verified flag, promoted/featured flag, search context that surfaced the record, and an ISO-8601 `scrapedAt` timestamp

The dataset is the fastest way to populate a **medical-tourism comparison platform**, build **price benchmarks for dental implants in Istanbul or hair-transplant clinics in Antalya**, audit **insurance networks against a real-world clinic catalog**, or generate **targeted B2B lead lists** for medical-device, SaaS, marketing and travel-services vendors selling into private healthcare.

#### Why scrape WhatClinic yourself when this exists?

WhatClinic.com is exceptionally rich data — and exceptionally painful to scrape. Most engineers who try get blocked within minutes:

- **TLS fingerprinting blocks Node and curl** — bare HTTP clients receive a `Client-OldBrowserSpam` rejection. WhatClinic checks the TLS handshake, not just the user-agent string, so requests must come from a real Chrome browser
- **JavaScript-rendered listing cards** — search result blocks (`clinicResult`, `provider-result`, `listing-result`) are hydrated client-side; raw HTML alone misses ServiceScores, prices and review counts
- **Cookie-consent walls** — the first hit on each session must accept the GDPR banner before content is served, otherwise you get a stripped page
- **403 / 429 / 503 rotation** — bursts of requests trigger anti-bot escalation; you need warmup, throttling and proxy rotation on each retry
- **Inconsistent card markup across categories** — dental, cosmetic and fertility listings use slightly different class names; one parser does not fit all
- **Multi-currency price strings** — `From €1,800`, `From £950`, `From ₺18.000`, `From ฿45,000`, `From ₹1,20,000` all need currency detection and numeric normalization
- **URL slug drift** — `dental` in the UI is `dentists/` in URLs, and city paths include the province (`istanbul-province/istanbul/`); a naive `category/country/city` URL builder breaks
- **Pagination via `?page=N` with no canonical total count** — you must detect the `rel="next"` link or stop when a page returns zero new clinics
- **Detail pages are slow and JS-heavy** — full address, opening hours, treatments, doctor names and photos live on profile pages that need full DOM rendering
- **Schema drift** — WhatClinic ships A/B tests; selectors that worked last month silently return null this month

This actor solves all of that: **real Chromium via Playwright, automatic cookie acceptance, homepage warmup, proxy fallback on 403/429/503, multi-pattern card parser, JSON-LD harvesting on profile pages, and a stable flat output schema** — so you stop maintaining HTML parsers and start shipping product features.

***

### Quick Start

#### One-Click Run

1. Open the [WhatClinic.com Clinic Scraper](https://apify.com/haketa/whatclinic-scraper) page on Apify
2. Click **Try for free** — the prefilled input runs `categories: ["hair-loss"]`, `countries: ["turkey"]`, `maxListings: 50`
3. Hit **Start** — within a few minutes the dataset is populated with Turkish hair-loss clinics ranked by ServiceScore
4. Open the dataset and download as **JSON, CSV, Excel, JSONL, HTML or XML** — or send it straight to Google Sheets via Apify's integrations panel

#### API Run (Python)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("haketa/whatclinic-scraper").call(run_input={
    "categories":      ["dental", "cosmetic-surgery"],
    "countries":       ["turkey", "thailand", "hungary"],
    "minServiceScore": 8.0,
    "scrapeDetails":   True,
    "maxListings":     500,
    "maxPages":        10,
    "proxyConfiguration": {"useApifyProxy": True, "apifyProxyGroups": ["RESIDENTIAL"]}
})

for clinic in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(
        clinic["clinicName"],
        "|", clinic["city"], clinic["country"],
        "|", clinic["serviceScore"], clinic["serviceScoreLabel"],
        "|", clinic["priceFrom"], "→", clinic["priceCurrency"], clinic["priceNumeric"],
    )
```

#### API Run (Node.js / TypeScript)

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

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

const run = await client.actor('haketa/whatclinic-scraper').call({
    categories:      ['hair-loss'],
    countries:       ['turkey'],
    cities:          ['istanbul-province/istanbul', 'antalya-province/antalya'],
    minServiceScore: 7.5,
    scrapeDetails:   true,
    maxListings:     300,
    maxPages:        8,
    requestDelay:    2000,
    maxConcurrency:  1,
    proxyConfiguration: { useApifyProxy: true, apifyProxyGroups: ['RESIDENTIAL'] },
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} hair-transplant clinics across Istanbul and Antalya`);
```

#### API Run (cURL)

```bash
curl -X POST "https://api.apify.com/v2/acts/haketa~whatclinic-scraper/runs?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "categories":      ["fertility"],
        "countries":       ["spain", "czech-republic", "greece"],
        "minServiceScore": 8.5,
        "scrapeDetails":   true,
        "maxListings":     200
      }'
```

#### API Run (direct profile URLs)

```python
run = client.actor("haketa/whatclinic-scraper").call(run_input={
    "startUrls": [
        {"url": "https://www.whatclinic.com/hair-loss/turkey/istanbul-province/istanbul/cosmedica-hair-transplant"},
        {"url": "https://www.whatclinic.com/dentists/thailand/bangkok/bangkok-international-dental-center"}
    ],
    "scrapeDetails": True
})
```

***

### How It Works

WhatClinic.com is a **TLS-fingerprinted, JavaScript-hydrated, GDPR-walled** site. Naive HTTP scrapers get a `403 Client-OldBrowserSpam` response within seconds. The actor's architecture works around every obstacle:

1. **Engine:** Headless Chromium via Playwright — a real browser with a real TLS handshake. No `axios`, no `got`, no `node-fetch`
2. **Warmup:** The first hit per session visits `https://www.whatclinic.com/` to set country-detection cookies, then automatically clicks the GDPR consent banner (`button:has-text("Accept")`)
3. **Resource blocking:** Images, fonts and trackers are blocked to keep page weight low while preserving JS and CSS execution
4. **Anti-bot rotation:** Attempt 1 runs direct; attempts 2–3 swap in a fresh Apify residential IP and back off exponentially on `403 / 429 / 503`
5. **Listing parser:** Multi-pattern regex extraction over the rendered HTML — handles both legacy (`clinicResult`) and current (`provider-result`, `listing-result`, `result-card`) card class names, plus a fallback that mines profile-link slugs when no structured block is present
6. **Detail enrichment (hybrid JSON-LD + DOM):** Optional second pass per clinic fetches the profile page and combines two complementary extractors:
   - **Comprehensive JSON-LD `MedicalClinic` / `Dentist` / `LocalBusiness` harvest** — pulls `aggregateRating`, `review[]`, `openingHoursSpecification`, `availableService` (treatments + prices), `paymentAccepted`, `currenciesAccepted`, `geo` (lat/lng), `sameAs` (social links), `email`, `url`, `foundingDate`, `priceRange`, `award`, `hasCredential`, `availableLanguage`
   - **Live DOM evaluator via `page.evaluate`** — extracts individual review cards, hours tables, treatment-price rows, social links and contact info that JSON-LD does not serve (or serves partially)
   - **Smart author parsing** — splits messy WhatClinic author strings like `"23.02.2026 Darko, Malta ( Review verified by phone )"` into clean `{author: "Darko", country: "Malta", verifiedBy: "phone", date: "23.02.2026"}` — preserving patient origin country for medical-tourism intelligence
7. **Price normalization:** Currency symbols (`€`, `£`, `$`, `₺`, `฿`, `₹`, `Ft`, `zł`, `R$`) are mapped to ISO codes; numeric values are stripped of thousand separators and parsed as floats
8. **Deduplication:** A run-scoped `Set` keyed on `profileUrl` ensures the same clinic is never written twice, even when it appears on multiple search paths

> **Verified live on Metropolmed Istanbul:** 13 real testimonials extracted with patient names, **patient origin country** (Malta, Ireland, Bulgaria, Romania, Turkey — medical-tourism critical), date, verification method (phone / email), and full multi-paragraph text.

#### Source endpoints

| Path Template | Purpose |
|---|---|
| `https://www.whatclinic.com/{category}/{country}/` | Country-level listing for a category |
| `https://www.whatclinic.com/{category}/{country}/?page={N}` | Pagination (~15–20 clinics/page) |
| `https://www.whatclinic.com/{category}/{country}/{province}/{city}/` | City-level drill-down (e.g. `istanbul-province/istanbul/`) |
| `https://www.whatclinic.com/{category}/{country}/{province}/{city}/{clinic-slug}` | Individual clinic profile page |

#### Category URL slug map

The UI category label and the URL slug occasionally differ. The actor maps them automatically:

| Input Slug | URL Path Segment | Display Label |
|---|---|---|
| `dental` | `dentists` | Dental |
| `hair-loss` | `hair-loss` | Hair Loss |
| `cosmetic-surgery` | `cosmetic-surgery` | Cosmetic Surgery |
| `eye-surgery` | `eye-surgery` | Eye Surgery |
| `fertility` | `fertility` | Fertility |
| `physiotherapy` | `physiotherapy` | Physiotherapy |
| `skin-care` | `skin-care` | Skin Care |
| `weight-loss` | `weight-loss` | Weight Loss |

***

### Input Parameters

```json
{
  "categories":      ["hair-loss", "dental"],
  "countries":       ["turkey", "thailand"],
  "cities":          ["istanbul-province/istanbul"],
  "startUrls":       [],
  "minServiceScore": 8.0,
  "scrapeDetails":   true,
  "maxListings":     500,
  "maxPages":        10,
  "requestDelay":    1500,
  "maxConcurrency":  1,
  "proxyConfiguration": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

#### Parameter reference

| Parameter | Type | Default | Description |
|---|---|---|---|
| `categories` | `array<string>` | all 8 | Treatment verticals to scrape. Allowed: `hair-loss`, `cosmetic-surgery`, `dental`, `eye-surgery`, `fertility`, `physiotherapy`, `skin-care`, `weight-loss`. Empty array = all categories. |
| `countries` | `array<string>` | `[]` | Country slugs. Examples: `turkey`, `thailand`, `hungary`, `india`, `spain`, `mexico`, `uk`, `usa`, `brazil`, `poland`, `united-arab-emirates`. See coverage table below. |
| `cities` | `array<string>` | `[]` | Optional city slugs (typically `province/city`). Example for Turkey: `istanbul-province/istanbul`, `antalya-province/antalya`, `izmir-province/izmir`. Leave empty to search the whole country. |
| `startUrls` | `array<object>` | `[]` | Direct WhatClinic listing or profile URLs. Overrides category/country/city if used. Format: `[{"url": "https://www.whatclinic.com/..."}]`. |
| `minServiceScore` | `number` | `0` | Filter — only keep clinics with `serviceScore >= this`. Range 0–10. Set 0 to disable. |
| `scrapeDetails` | `boolean` | `false` | When `true`, the actor visits each clinic's profile page for address, opening hours, treatments, prices, staff, description and photos. Slower but much richer. |
| `maxListings` | `integer` | `50` | Cap on total clinics saved across all searches. Set `0` for unlimited. |
| `maxPages` | `integer` | `5` | Cap on pages per `category × country × city` combination. Set `0` for unlimited. |
| `requestDelay` | `integer` (ms) | `1000` | Pause between requests. WhatClinic dislikes bursts — keep ≥ 1500 ms in production. Max `30000`. |
| `maxConcurrency` | `integer` | `1` | Parallel browser contexts. Keep `1–3` to avoid rate limiting. Max `5`. |
| `proxyConfiguration` | `object` | Apify proxy on | Apify proxy spec. **Residential is recommended** for any non-trivial run; datacenter IPs are blocked quickly. |

***

### Output Schema

Every record uses the same flat JSON shape — whether it came from a listing card or an enriched profile page — so downstream consumers do not need per-source branching.

#### Identity & location

| Field | Type | Description |
|---|---|---|
| `clinicName` | `string` | Clinic display name (e.g. `Bangkok International Dental Center`) |
| `profileUrl` | `string` | Absolute URL to the WhatClinic profile page |
| `category` | `string` | Display label (e.g. `Hair Loss`, `Dental`, `Cosmetic Surgery`) |
| `country` | `string` | Country name as shown on WhatClinic |
| `city` | `string` | City name (Title-cased) |
| `district` | `string \| null` | Sub-area within city, when available on profile pages |
| `address` | `string \| null` | Street address (filled when `scrapeDetails: true`) |
| `postalCode` | `string \| null` | Postal / ZIP code parsed from JSON-LD `address.postalCode` |
| `phone` | `string \| null` | Phone number from profile page or JSON-LD |
| `email` | `string \| null` | Clinic email — extracted from JSON-LD or DOM `mailto:` links when published |
| `website` | `string \| null` | External clinic website URL (JSON-LD `url` or DOM contact block) |
| `latitude` | `number \| null` | Geographic latitude from JSON-LD `geo.latitude` |
| `longitude` | `number \| null` | Geographic longitude from JSON-LD `geo.longitude` |
| `socialLinks` | `array<string> \| null` | Facebook / Instagram / YouTube / LinkedIn / Twitter URLs from JSON-LD `sameAs` and DOM social bar |

#### Reputation signals

| Field | Type | Description |
|---|---|---|
| `serviceScore` | `number \| null` | WhatClinic proprietary score 0.0 – 10.0 |
| `serviceScoreLabel` | `string \| null` | Human label: `Outstanding`, `Excellent`, `Very Good`, `Good`, `Fair`, `Poor` |
| `interactionCount` | `integer \| null` | Number of inquiries / interactions feeding the score |
| `reviewCount` | `integer \| null` | Number of verified patient reviews |
| `averageRating` | `number \| null` | Patient rating average (0.0 – 5.0) |
| `ratingScale` | `number \| null` | Native rating scale used by the source (typically `5` or `10`) — needed to normalise `averageRating` across clinics |
| `awards` | `array<string> \| null` | Annual awards (e.g. `Customer Service Award 2024`, `Global Patients Award 2023`) |
| `reviews` | `array<object> \| null` | Individual patient testimonials. Each entry: `{author, country, verifiedBy, rating, text, date, treatment}`. `country` = patient origin (medical-tourism critical), `verifiedBy` = `phone` / `email` / `null`, `rating` often `null` (see FAQ). |

#### Treatment & pricing

| Field | Type | Description |
|---|---|---|
| `priceFrom` | `string \| null` | Starting price string as displayed (e.g. `From €1,800`) |
| `priceCurrency` | `string \| null` | ISO currency code: `EUR`, `GBP`, `USD`, `TRY`, `THB`, `INR`, `HUF`, `PLN`, `BRL` |
| `priceNumeric` | `number \| null` | Parsed numeric value (no separators) |
| `treatments` | `array<string> \| null` | Treatment menu (profile-page enrichment) |
| `treatmentPrices` | `array<object> \| null` | Per-treatment price rows when listed on the profile |

#### Profile depth (when `scrapeDetails: true`)

| Field | Type | Description |
|---|---|---|
| `openingHours` | `object \| null` | `{ monday: "9:00 - 18:00", tuesday: "9:00 - 18:00", ... }` — merged from JSON-LD `openingHoursSpecification` and on-page hours tables |
| `staffNames` | `array<string> \| null` | Listed doctors / specialists |
| `description` | `string \| null` | Long-form clinic description |
| `photos` | `array<string> \| null` | Gallery image URLs (logos / avatars stripped) |
| `foundingDate` | `string \| null` | Year the clinic was founded (JSON-LD `foundingDate`) |
| `paymentMethods` | `array<string> \| null` | Accepted payment methods (e.g. `Cash`, `Visa`, `MasterCard`, `Bank Transfer`) — JSON-LD `paymentAccepted` |
| `currenciesAccepted` | `array<string> \| null` | ISO currency codes the clinic transacts in (`EUR`, `USD`, `TRY`, …) |
| `languages` | `array<string> \| null` | Languages spoken by staff — JSON-LD `availableLanguage` plus DOM "Languages spoken" block |
| `credentials` | `array<string> \| null` | Accreditations / certifications (JCI, ISO 9001, ministry-of-health licences, etc.) from JSON-LD `hasCredential` |

#### Status & metadata

| Field | Type | Description |
|---|---|---|
| `verified` | `boolean \| null` | `true` if the listing displays a "verified" badge / review marker |
| `promoted` | `boolean \| null` | `true` if Featured / Promoted / Premium / Sponsored placement |
| `searchCategory` | `string` | Input category that surfaced this clinic |
| `searchCountry` | `string` | Input country that surfaced this clinic |
| `searchCity` | `string \| null` | Input city (or `null` for whole-country searches) |
| `scrapedAt` | `string` | ISO-8601 UTC timestamp of extraction |

#### Example: Hair transplant clinic (Istanbul)

```json
{
  "clinicName": "Cosmedica Hair Transplant",
  "profileUrl": "https://www.whatclinic.com/hair-loss/turkey/istanbul-province/istanbul/cosmedica-hair-transplant",
  "category": "Hair Loss",
  "country": "Turkey",
  "city": "Istanbul",
  "district": "Şişli",
  "address": "Esentepe Mh. Büyükdere Cd.",
  "postalCode": "34394",
  "phone": "+90 212 999 99 99",
  "email": "info@cosmedica.example",
  "website": "https://www.cosmedica.example/",
  "latitude": 41.0766,
  "longitude": 29.0103,
  "serviceScore": 9.8,
  "serviceScoreLabel": "Outstanding",
  "interactionCount": 412,
  "reviewCount": 187,
  "averageRating": 4.9,
  "ratingScale": 5,
  "awards": ["Customer Service Award 2024", "Global Patients Award 2023"],
  "reviews": [
    {
      "author": "Darko",
      "country": "Malta",
      "verifiedBy": "phone",
      "rating": null,
      "text": "Excellent treatment from start to finish, the team made me feel safe throughout the whole procedure.",
      "date": "23.02.2026",
      "treatment": "FUE Hair Transplant"
    }
  ],
  "foundingDate": "2012",
  "paymentMethods": ["Cash", "Visa", "MasterCard", "Bank Transfer"],
  "currenciesAccepted": ["EUR", "USD", "TRY", "GBP"],
  "languages": ["English", "Turkish", "German", "Arabic"],
  "credentials": ["ISO 9001", "Turkish Ministry of Health Licensed"],
  "socialLinks": [
    "https://www.facebook.com/cosmedicaclinic",
    "https://www.instagram.com/cosmedicaclinic"
  ],
  "priceFrom": "From €1,800",
  "priceCurrency": "EUR",
  "priceNumeric": 1800,
  "openingHours": {
    "monday":    "9:00 - 18:00",
    "tuesday":   "9:00 - 18:00",
    "wednesday": "9:00 - 18:00",
    "thursday":  "9:00 - 18:00",
    "friday":    "9:00 - 18:00",
    "saturday":  "9:00 - 16:00"
  },
  "treatments": ["FUE Hair Transplant", "DHI Hair Transplant", "Sapphire FUE", "Beard Transplant", "Eyebrow Transplant"],
  "treatmentPrices": null,
  "staffNames": ["Dr. Levent Acar"],
  "description": "Cosmedica Hair Transplant is one of Istanbul's most recognised hair restoration clinics specialising in FUE, DHI and Sapphire FUE techniques for international patients.",
  "photos": [
    "https://images.whatclinic.com/example/clinic-1.jpg",
    "https://images.whatclinic.com/example/clinic-2.jpg"
  ],
  "verified": true,
  "promoted": true,
  "searchCategory": "hair-loss",
  "searchCountry": "turkey",
  "searchCity": "istanbul-province/istanbul",
  "scrapedAt": "2026-05-16T11:22:33.000Z"
}
```

#### Example: Dental clinic (Budapest)

```json
{
  "clinicName": "Helvetic Clinics Budapest",
  "profileUrl": "https://www.whatclinic.com/dentists/hungary/central-hungary/budapest/helvetic-clinics-budapest",
  "category": "Dental",
  "country": "Hungary",
  "city": "Budapest",
  "district": null,
  "address": null,
  "phone": null,
  "serviceScore": 9.4,
  "serviceScoreLabel": "Excellent",
  "interactionCount": 268,
  "reviewCount": 142,
  "averageRating": 4.8,
  "awards": ["Global Patients Award 2024"],
  "priceFrom": "From €290",
  "priceCurrency": "EUR",
  "priceNumeric": 290,
  "openingHours": null,
  "treatments": null,
  "treatmentPrices": null,
  "staffNames": null,
  "description": null,
  "photos": null,
  "verified": true,
  "promoted": false,
  "searchCategory": "dental",
  "searchCountry": "hungary",
  "searchCity": null,
  "scrapedAt": "2026-05-16T11:22:33.000Z"
}
```

***

### ServiceScore Reference

WhatClinic's proprietary **ServiceScore** is a 0–10 metric combining inquiry response time, response quality, conversion behaviour and verified review data. The actor exposes both the raw score and the human label so you can filter, sort and display either.

| Label | Score Range | Meaning |
|---|---|---|
| **Outstanding** | 9.5 – 10.0 | Top-tier responsiveness and patient experience |
| **Excellent** | 9.0 – 9.4 | Very high-performing clinic |
| **Very Good** | 8.0 – 8.9 | Above-average service quality |
| **Good** | 7.0 – 7.9 | Solid baseline — meets WhatClinic standards |
| **Fair** | 5.0 – 6.9 | Mixed signals — review before referral |
| **Poor** | 0.0 – 4.9 | Significant service issues |

> **Tip:** Combine `minServiceScore: 8.0` with `verified: true` filters downstream to build a curated, high-trust referral list.

### Treatment Category Reference

| Slug | Display | What's Inside |
|---|---|---|
| `hair-loss` | Hair Loss | FUE, DHI, Sapphire FUE, beard & eyebrow transplants, PRP, mesotherapy |
| `dental` | Dental | Implants, veneers, crowns, All-on-4 / All-on-6, orthodontics, whitening, smile makeovers |
| `cosmetic-surgery` | Cosmetic Surgery | Rhinoplasty, breast aug/lift, liposuction, BBL, facelift, blepharoplasty, body contouring |
| `eye-surgery` | Eye Surgery | LASIK, PRK, SMILE, ICL, cataract, lens replacement, retinal |
| `fertility` | Fertility | IVF, ICSI, IUI, egg/sperm freezing, donor cycles, surrogacy programs |
| `physiotherapy` | Physiotherapy | Sports rehab, post-op, manual therapy, neurological rehab |
| `skin-care` | Skin Care | Dermatology, laser, peels, fillers, botox, acne, pigmentation |
| `weight-loss` | Weight Loss | Gastric sleeve, bypass, balloon, mini-bypass, revision bariatrics |

***

### Use Cases

#### Medical-Tourism Agencies & Travel Concierges

Medical-tourism agencies use the dataset as the spine of their **clinic-matching, quote-generation and referral pipelines**:

- **Build a multi-country comparison engine** — IVF in Spain vs. Czech Republic vs. Greece, ranked by ServiceScore and starting price
- **Generate one-click client quotes** by joining `priceNumeric` × `priceCurrency` with live FX rates
- **Curate "verified by WhatClinic" referral lists** with `verified: true` and `minServiceScore: 8.5` filters
- **Track award winners** (Customer Service Award, Global Patients Award) to highlight in marketing collateral
- **Refresh the clinic catalog weekly** so new openings in Istanbul, Antalya, Bangkok or Mexico City appear in the funnel automatically
- **Identify language-friendly clinics** by enriching with the description text via downstream NLP
- **Map patient-origin geography per clinic** — aggregate the `country` field across `reviews[]` to see exactly which nationalities each clinic already attracts (e.g. Metropolmed Istanbul draws Malta, Ireland, Bulgaria, Romania), then target lookalike audiences in marketing
- **Run sentiment analysis on individual testimonials** (`reviews[].text`) to score patient experience beyond a 5-star average — surface complaint patterns and standout praise per clinic
- **Use verification trust signals** (`reviews[].verifiedBy = "phone"` vs `"email"` vs `null`) to weight review credibility in your ranking algorithm
- **Direct outreach with `email`, `website`, `socialLinks`, lat/lng** — bypass the WhatClinic contact form for partnership conversations and plot clinics on maps for territory planning

#### Dental & Cosmetic Price-Benchmarking Platforms

Cost-comparison startups (think "Kayak for dental implants") use the actor to **build the price index that drives the product**:

- **Crawl dental implant prices** across Hungary, Turkey, Spain, Poland, Mexico and Thailand in one run
- **Compute median, p25, p75 price bands** per treatment × country using `priceNumeric`
- **Detect undercutting or premium pricing** clinic-by-clinic vs. national benchmark
- **Surface savings vs. home country** — "Save 65% on All-on-4 vs. UK average"
- **Power "price drop" alerts** when a clinic's `priceFrom` falls below a threshold
- **Feed an affiliate / lead-generation funnel** with the strongest price-quality combinations

#### Insurance & Provider Network Audits

Health insurers, travel-medical underwriters and TPAs use WhatClinic data as an **external reality check** on their preferred-provider networks:

- **Audit network gaps** — does your Bangkok cosmetic-surgery network include the top-10 by ServiceScore?
- **Identify high-quality non-network clinics** that members are likely to choose out-of-pocket
- **Detect disqualifying signals** (low review count, low score, no awards) before adding a clinic
- **Negotiate pricing** with hard data on the local competitive band
- **Validate provider directories** monthly against an independent source
- **Support international utilization-management decisions** with current third-party reputation data

#### B2B Sales & Lead Generation (Medical Devices, SaaS, Marketing Services)

Vendors selling **into private clinics** — implant manufacturers, EMR / PMS SaaS, dental imaging, surgical lasers, clinic-marketing agencies — use the actor to **build precision target lists**:

- **Filter by category × country × city** to match sales territories
- **Score leads by ServiceScore, review count and award presence** as proxies for budget and growth
- **Enrich Salesforce / HubSpot** with phone, address and profile URL via license-number-style upsert keys
- **Detect "Featured" / promoted clinics** — known WhatClinic advertisers signal marketing-budget readiness
- **Identify multi-location chains** (matching brand fragments) for enterprise outreach
- **Track new clinic openings month-over-month** by diffing successive runs

#### Healthcare M\&A and Investor Research

Private equity, VC and corporate-development teams evaluating clinic chains, consolidator plays and roll-up theses use the dataset for **bottoms-up market mapping**:

- **Size the addressable supply** of dental, hair-loss or fertility clinics in a target geography
- **Map competitive density** at the city / district level
- **Benchmark ServiceScore distributions** before acquiring a chain
- **Detect emerging hubs** — fastest-growing cities for cosmetic-surgery clinics
- **Build acquisition target screens** with `verified: true`, score ≥ 9.0, ≥ 100 reviews
- **Cross-reference with public-licensing data** (NPI, CA DCA, TSBP, Ohio eLicense) for clinics with US footprints

#### Academic, Public-Health & Workforce Research

Health economists, global-health researchers and journalists use WhatClinic data to **quantify private-clinic supply** in markets where official statistics are sparse:

- **Map medical-tourism gravity flows** — origin countries vs. destination clinic clusters
- **Quantify private-sector dental capacity** in middle-income countries
- **Study price dispersion** across categories and currencies
- **Track award concentration** as a proxy for sector consolidation
- **Build reproducible datasets** for peer-reviewed publication on global private healthcare
- **Investigate consumer-protection issues** — clinics with low scores yet heavy promotion

#### Clinic Marketing & Reputation Management

Clinic owners and reputation-management agencies monitor their own and competitor presence on WhatClinic to **defend and grow market share**:

- **Track week-over-week ServiceScore changes** for the clinic and top-10 local competitors
- **Benchmark review velocity** — are competitors gaining reviews faster?
- **Audit price positioning** vs. neighbourhood / city median
- **Surface new entrants** in the local competitive set
- **Detect lost award status** or promotion downgrades
- **Inform PPC and SEO campaign budgets** with category × city demand signals

#### Investigative & Consumer-Affairs Journalism

Reporters covering medical tourism, cosmetic-surgery safety, fertility ethics and international dental fraud use the dataset for **scoped, reproducible reporting**:

- **Identify clinics promoting aggressively at the lowest end of the price band**
- **Compare advertised prices vs. patient-reported actuals**
- **Trace ownership patterns** across clinic chains with similar branding
- **Document "promoted" placement bias** in directory listings
- **Build country-by-country safety dashboards** combining WhatClinic data with regulator records

#### Travel, Hospitality & Concierge Tech

Hotels, travel-tech platforms and concierge apps near major medical-tourism hubs use the data to **bundle care with stays and transfers**:

- **Power "stay near a top clinic" search** in Istanbul, Antalya, Bangkok, Mumbai, Budapest
- **Match accommodation tier to clinic tier** (luxury hair-transplant + 5-star hotel package)
- **Build aftercare-friendly itineraries** based on opening hours and treatment durations
- **Localize landing pages** with current clinic counts and review aggregates per city

***

### Sample Queries & Recipes

#### Recipe 1 — Top-tier hair-transplant clinics in Turkey

```json
{
  "categories":      ["hair-loss"],
  "countries":       ["turkey"],
  "minServiceScore": 9.0,
  "scrapeDetails":   true,
  "maxListings":     200,
  "maxPages":        15
}
```

Goal: a curated list of award-class Turkish hair-transplant clinics for a medical-tourism affiliate site.

#### Recipe 2 — Budapest dental implants under €1,000 starting price

```json
{
  "categories":    ["dental"],
  "countries":     ["hungary"],
  "cities":        ["central-hungary/budapest"],
  "scrapeDetails": true,
  "maxListings":   100
}
```

Post-filter downstream on `priceNumeric < 1000 and priceCurrency == "EUR"`.

#### Recipe 3 — IVF clinic comparison across Spain, Czech Republic and Greece

```json
{
  "categories":      ["fertility"],
  "countries":       ["spain", "czech-republic", "greece"],
  "minServiceScore": 8.5,
  "scrapeDetails":   true,
  "maxListings":     300,
  "maxPages":        10
}
```

#### Recipe 4 — Bangkok cosmetic-surgery competitive map

```json
{
  "categories":    ["cosmetic-surgery"],
  "countries":     ["thailand"],
  "cities":        ["central-thailand/bangkok"],
  "scrapeDetails": true,
  "maxListings":   250
}
```

#### Recipe 5 — Mexico City weight-loss / bariatric clinic lead list

```json
{
  "categories":    ["weight-loss"],
  "countries":     ["mexico"],
  "cities":        ["mexico-city/mexico-city"],
  "minServiceScore": 7.5,
  "maxListings":   150
}
```

#### Recipe 6 — Eye-surgery clinics in Dubai (UAE)

```json
{
  "categories":    ["eye-surgery"],
  "countries":     ["united-arab-emirates"],
  "cities":        ["dubai/dubai"],
  "scrapeDetails": true,
  "maxListings":   80
}
```

#### Recipe 7 — Direct profile enrichment for a known shortlist

```json
{
  "startUrls": [
    {"url": "https://www.whatclinic.com/dentists/hungary/central-hungary/budapest/helvetic-clinics-budapest"},
    {"url": "https://www.whatclinic.com/hair-loss/turkey/istanbul-province/istanbul/cosmedica-hair-transplant"},
    {"url": "https://www.whatclinic.com/cosmetic-surgery/thailand/central-thailand/bangkok/yanhee-international-hospital"}
  ],
  "scrapeDetails": true
}
```

#### Recipe 8 — Sample run for evaluation (cheap and fast)

```json
{
  "categories":  ["dental"],
  "countries":   ["turkey"],
  "maxListings": 20,
  "maxPages":    2
}
```

***

### Integration Examples

#### Google Sheets (no-code)

1. Schedule the actor daily / weekly in the Apify Console
2. Attach the **Google Sheets** integration on the schedule
3. Receive a fresh clinic sheet (overview view: name / category / country / city / score / price / awards) in your Drive every morning — ready for filtering, pivot tables and Looker Studio dashboards

#### Make.com / Zapier / n8n

Use the **Apify** connector to wire dataset events into downstream workflows:

- New clinic added → Slack notification to the BD team
- ServiceScore drop > 1.0 → Open a Linear / Jira ticket for the account manager
- Price change > 20% → Email alert to the pricing analyst
- New award detected → Auto-tag in HubSpot as `tier-1-target`

#### Power BI / Tableau / Looker Studio

Connect Apify's REST API as a data source and build:

- ServiceScore distribution by category × country
- Median price bands per treatment per city
- Award concentration heatmap
- Clinic supply growth trend (run-over-run diff)
- Country share-of-supply pie charts

#### Postgres / Snowflake / BigQuery

Use Apify's [webhook integration](https://docs.apify.com/platform/integrations/webhooks) to POST run results to your warehouse ingestion endpoint. Suggested keys:

- Primary: `profileUrl`
- Partition: `searchCountry` / `searchCategory`
- Slowly-changing: `serviceScore`, `priceNumeric`, `reviewCount`, `awards`

#### Salesforce / HubSpot CRM Enrichment

Schedule nightly, then upsert against Account records keyed on `profileUrl`. Score changes can auto-create Tasks; new awards can trigger lifecycle-stage promotions.

#### Custom Apps (Python / Node)

The `apify-client` SDKs stream dataset items directly, so a Flask / FastAPI / Next.js app can render live clinic data without re-implementing the scraper.

***

### Major Markets & Regional Coverage

WhatClinic indexes clinics in 160+ countries. The actor handles every market the site exposes via its category-country URL pattern. The table below highlights the most-trafficked medical-tourism and private-healthcare hubs.

| Market | Hub Cities | Strongest Verticals |
|---|---|---|
| **Turkey** | Istanbul, Antalya, Izmir, Ankara, Bodrum | Hair transplant, dental, cosmetic surgery, eye surgery |
| **Thailand** | Bangkok, Phuket, Chiang Mai, Pattaya | Cosmetic surgery, dental, gender-affirming, weight loss |
| **Hungary** | Budapest, Sopron, Mosonmagyaróvár | Dental, cosmetic surgery |
| **Mexico** | Mexico City, Tijuana, Cancún, Guadalajara, Los Algodones | Dental, weight loss, cosmetic surgery |
| **India** | Mumbai, Delhi, Bangalore, Chennai, Hyderabad | Fertility, cosmetic, dental, eye surgery |
| **Spain** | Madrid, Barcelona, Valencia, Marbella | Fertility, cosmetic surgery, dental |
| **Poland** | Warsaw, Kraków, Wrocław, Gdańsk | Dental, cosmetic surgery |
| **Czech Republic** | Prague, Brno | Fertility, cosmetic surgery, dental |
| **UAE** | Dubai, Abu Dhabi, Sharjah | Cosmetic surgery, dental, dermatology |
| **United Kingdom** | London, Manchester, Birmingham, Edinburgh, Glasgow | Dental, cosmetic surgery, fertility, hair loss |
| **Germany** | Berlin, Munich, Hamburg, Frankfurt | Dental, fertility, cosmetic surgery |
| **United States** | New York, Los Angeles, Miami, Chicago, Houston | Dental, cosmetic surgery, eye surgery, fertility |
| **Brazil** | São Paulo, Rio de Janeiro, Curitiba | Cosmetic surgery, dental |
| **South Korea** | Seoul, Busan | Cosmetic surgery, dental |
| **Malaysia** | Kuala Lumpur, Penang | Cosmetic, dental, fertility |
| **Greece** | Athens, Thessaloniki | Fertility, dental |
| **Costa Rica** | San José, Escazú | Dental, cosmetic surgery |
| **Colombia** | Bogotá, Medellín, Cali | Cosmetic surgery, dental |

> **Tip:** Country slugs follow WhatClinic's URL convention — lowercase, hyphenated (`united-arab-emirates`, `czech-republic`, `south-korea`). City slugs include the province segment (`istanbul-province/istanbul`).

***

### Cost & Performance

| Metric | Value |
|---|---|
| Engine | Headless Chromium via Playwright (real Chrome TLS fingerprint) |
| Runtime (listings only, 100 clinics, single country) | ~3–6 minutes |
| Runtime (with `scrapeDetails: true`, 100 clinics) | ~12–25 minutes |
| Pricing model | Pay-per-event (transparent per-record + per-start billing) |
| Cost per run | Varies with `maxListings` × `scrapeDetails`; typical small runs a few cents |
| Data freshness | **Live at run time** — WhatClinic is queried in real time on each request |
| Auth required | None |
| Proxy required | **Residential strongly recommended** (datacenter IPs get 403'd) |
| Concurrency | Default 1, max 5 — keep low to avoid 429/503 escalation |
| Memory footprint | 1024 MB recommended (browser overhead) |
| Failure mode | Per-page graceful: 403/429/503 triggers proxy rotation + backoff up to 3 attempts |

***

### Compliance, Privacy & Legal Notes

- **Public data only** — every field is published on WhatClinic.com to anyone visiting the site without an account
- **No PHI** — the dataset contains clinic business information and **publicly displayed patient testimonials** (first name + country of origin, as the patient and WhatClinic chose to publish them). No medical records, no diagnoses, no protected health information
- **Business addresses, phones, emails & websites** — these fields represent the clinic's published business contact details, not personal information
- **Reviewer privacy** — the `reviews[]` array contains only the first name / handle, country and verification flag the reviewer themselves consented to publish on WhatClinic. The actor does not attempt to deanonymise reviewers or join across clinics
- **HIPAA does not apply** — this is directory data, not protected health information
- **GDPR / CCPA** — business-entity directory data falls outside most personal-data protections; downstream use (e.g. marketing outreach) remains the consumer's responsibility under CAN-SPAM, TCPA, GDPR ePrivacy and equivalents
- **robots.txt & ToS** — the actor respects polite scraping conventions: throttled requests, low concurrency, residential proxy, no login circumvention. Confirm WhatClinic's current Terms of Service align with your intended use
- **Trademarks** — WhatClinic, ServiceScore, Customer Service Award and Global Patients Award are trademarks of their respective owners. This actor is an independent extraction tool and is not affiliated with, endorsed by, or sponsored by WhatClinic.com

> **Important:** Do not use this data to mislead patients about clinic affiliations, fabricate reviews, or impersonate clinics. Bulk marketing outreach to listed clinics must comply with local anti-spam laws.

***

### Frequently Asked Questions

#### How fresh is the data?

**Live at run time.** WhatClinic is queried in real time on every actor run — there is no cached layer. ServiceScores, prices, awards and review counts reflect what was on the site the moment the run executed.

#### How many clinics can I extract per run?

There is no hard cap from the actor side — `maxListings: 0` means unlimited. Practical limits come from WhatClinic's anti-bot behaviour: with `maxConcurrency: 1`, `requestDelay: 1500` and residential proxies, expect 500–2,000 clinics per hour. Larger runs should be split into multiple scheduled jobs.

#### Do I need a WhatClinic account or API key?

No. WhatClinic does not offer a public API. The actor reads the same publicly-rendered HTML that a human visitor sees — no login, no token, no scraping account.

#### Why does WhatClinic block plain HTTP clients?

WhatClinic uses TLS fingerprinting in addition to user-agent checks. Node's `fetch`, Python `requests` and `curl` all produce TLS handshakes that differ from real Chrome, and the server responds with `403 Client-OldBrowserSpam`. The actor sidesteps this by running real Chromium via Playwright.

#### Do I need residential proxies?

For anything beyond a 10-clinic test run, yes. Apify datacenter IPs are quickly recognised and 403-blocked. The actor's input prefills `{ "useApifyProxy": true }`; switch the proxy group to `RESIDENTIAL` for production runs.

#### Which countries are supported?

Every country WhatClinic indexes — currently 160+. Major medical-tourism hubs (Turkey, Thailand, Hungary, Mexico, India, Spain, UAE, UK, Germany, US, Poland, Czech Republic, Brazil, Greece, Costa Rica, Colombia, Malaysia, South Korea) are battle-tested. Smaller markets work too — just use the same URL slug WhatClinic shows in its breadcrumb.

#### How do I find the right country / city slug?

Visit `whatclinic.com`, navigate to the category × country × city page you want, and copy the path segments from the URL. For example: `https://www.whatclinic.com/hair-loss/turkey/istanbul-province/istanbul/` → `countries: ["turkey"]`, `cities: ["istanbul-province/istanbul"]`.

#### What's the difference between `scrapeDetails: false` and `true`?

`false` (default): only listing-card data (name, score, label, price, reviews, awards). Fast and cheap. `true`: visits each clinic's profile page and adds address, opening hours, treatments, staff, description and photos. Slower but produces full profile records.

#### Can I filter by ServiceScore?

Yes — set `minServiceScore` (0–10). The actor discards any clinic whose score is below the threshold before writing it to the dataset.

#### Are patient reviews included in the output?

Yes. The actor extracts the **review count, average rating AND individual patient testimonials** when `scrapeDetails: true`. Each entry in the `reviews[]` array carries `{author, country, verifiedBy, rating, text, date, treatment}` — the full multi-paragraph review body plus metadata.

#### Can I extract individual patient reviews with country of origin?

**Yes — this is the headline feature.** Verified live on Metropolmed Istanbul, the actor pulls 13 real testimonials including patient name, **origin country** (Malta, Ireland, Bulgaria, Romania, Turkey), date, verification method (phone vs. email), treatment and full text. Sample shape:

```json
{
  "author": "Darko",
  "country": "Malta",
  "verifiedBy": "phone",
  "rating": null,
  "text": "Excellent treatment from start to finish, the team made me feel safe throughout the whole procedure.",
  "date": "23.02.2026",
  "treatment": "Hair Transplant"
}
```

Aggregate the `country` field across all reviews per clinic to build a **medical-tourism origin map** — invaluable for marketing intelligence and lookalike-audience targeting.

#### Why is `rating` often `null` on individual reviews?

WhatClinic does not expose per-review star ratings in its public review feed — only the **aggregate** `averageRating` and `reviewCount`. The actor populates `reviews[].rating` whenever a per-review score is published (some clinics surface it via JSON-LD), and leaves it `null` otherwise rather than fabricating a value. The aggregate field remains a reliable trust signal.

#### Can I get a clinic's email?

Yes — when the clinic publishes one. The actor extracts `email` from JSON-LD `email` properties and DOM `mailto:` links. Many clinics still prefer the WhatClinic contact form and do not publish an email; in those cases `email` is `null` and you should fall back to `phone`, `website` or `socialLinks`.

#### How complete are opening hours, treatments, prices and languages?

Partial — they depend on what each clinic chose to publish in its WhatClinic profile. Top-tier clinics typically populate everything (full weekly hours table, ten+ treatments with starting prices, languages, payment methods, credentials). Smaller or newer listings may publish only a subset; the actor returns `null` for fields the clinic did not provide rather than guessing.

#### Does the actor handle multi-currency pricing?

Yes — `priceFrom` keeps the original display string; `priceCurrency` exposes the ISO code (`EUR`, `GBP`, `USD`, `TRY`, `THB`, `INR`, `HUF`, `PLN`, `BRL`); `priceNumeric` is the parsed numeric value with separators stripped.

#### How do I avoid duplicates when running on a schedule?

The `profileUrl` field is a stable unique key — upsert against it in your warehouse / CRM. The actor itself deduplicates within a single run; across runs you can compare `profileUrl` to detect new vs. existing clinics.

#### Can I run multiple categories and countries in one run?

Yes. The actor builds the **Cartesian product** of `categories × countries × cities`. Three categories × five countries = 15 search tasks executed sequentially.

#### Does the actor capture promoted / featured placement?

Yes — `promoted: true` is set when the listing carries Featured / Promoted / Premium / Sponsored markers. Useful for tracking who is paying for visibility.

#### What happens on 403 / 429 / 503?

The browser session closes, a new Apify proxy IP is requested, and the page is retried up to 3 times with exponential backoff. After the third failure the actor logs a warning and moves on rather than crashing the run.

#### Can I run this on the Apify Free plan?

Yes for small runs (a few hundred listings). Larger / more frequent runs benefit from the paid tier for compute headroom and residential proxy quota.

#### Can I export to CSV / Excel / JSONL?

Yes — Apify datasets export to JSON, CSV, Excel (XLSX), JSONL, HTML, XML and RSS straight from the dataset UI. The REST API supports streaming JSONL for large warehouse loads.

#### Is there a "find clinics near a hotel" workflow?

Yes. When `scrapeDetails: true`, the actor returns `latitude` and `longitude` from JSON-LD `geo`, so you can run a spatial join against your hotel inventory directly. For clinics that don't publish geo in JSON-LD, fall back to geocoding the `address` + `postalCode` fields with Google, Mapbox or Nominatim.

#### How do I report a bug or request a feature?

Open an issue on the Apify Store page for this actor, or contact the developer directly via the Apify Console.

***

### Related Apify Actors by Haketa

Round out your healthcare and global-business data stack with these complementary actors:

#### Healthcare & Care

- [Bookimed.com Medical Tourism Scraper](https://apify.com/haketa/bookimed-scraper) — patient-facing medical-tourism marketplace covering specialised clinics, doctors and package pricing (perfect sibling for cross-validating WhatClinic data)
- [ProductHunt Launches & Makers Scraper](https://apify.com/haketa/producthunt-launches-scraper) — daily startup launches, makers, votes & reviews — VC/founder/recruiter intel

#### US Healthcare Licensing (for clinics with US footprints)

- [Texas Pharmacy License Scraper — TSBP](https://apify.com/haketa/tsbp-license-scraper) — every pharmacist, pharmacy, intern and tech in Texas
- [California DCA Professional License Scraper](https://apify.com/haketa/california-dca-license-scraper) — California Department of Consumer Affairs
- [Ohio eLicense Scraper](https://apify.com/haketa/ohio-elicense-scraper) — Ohio professional licenses
- [Illinois IDFPR License Scraper](https://apify.com/haketa/illinois-idfpr-license-scraper) — Illinois licensed professionals
- [Virginia DPOR Professional License Scraper](https://apify.com/haketa/virginia-dpor-license-scraper)
- [Colorado Professional License Scraper](https://apify.com/haketa/colorado-professional-license-scraper)

#### Trust, Verification & Compliance

- [BBB Business Scraper](https://apify.com/haketa/bbb-scraper) — Better Business Bureau ratings and complaint history
- [SAM.gov Federal Contractor Entity Scraper](https://apify.com/haketa/sam-gov-federal-contractor-scraper) — US federal contractor entity records

#### Global Property & Hospitality Adjacencies (for medical-tourism stay bundles)

- [Apartments.com Scraper (US)](https://apify.com/haketa/apartments-com-scraper)
- [Realtor.ca Scraper (Canada)](https://apify.com/haketa/realtor-ca-scraper)
- [Domain.com.au Property Scraper (Australia)](https://apify.com/haketa/domain-com-au-scraper)

***

### Comparison vs. Alternatives

| Approach | Setup time | Data freshness | Anti-bot handling | Schema normalization | Cost (100 clinics, full detail) |
|---|---|---|---|---|---|
| **This actor** | < 1 minute | Live at run time | Built-in (Playwright + proxy rotation) | Built-in | Pennies via pay-per-event |
| Manual copy-paste from WhatClinic | Hours per query | Instant | N/A | None | Free + heavy labour |
| `requests` / `axios` script | Hours to days | Live | Fails (TLS fingerprint block) | DIY | Free + dev time |
| Headless Chrome from scratch | Days to weeks | Live | DIY proxy + cookie + retry logic | DIY | High infra + maintenance |
| Paid third-party medical-tourism API | Days (sales cycle) | Often stale (cached) | N/A | Vendor-specific | Hundreds to thousands /mo |
| Hiring a VA team | Days to onboard | Days behind | N/A | Inconsistent | Recurring labour cost |

***

### Why Pay-Per-Event Pricing?

Most data tools either (a) charge a flat monthly subscription you pay even when you don't run anything, or (b) bill per opaque compute unit that's impossible to forecast. This actor uses **pay-per-event** pricing:

- You only pay for what the actor **delivers** — per actor start and per dataset item
- Charges scale with the data you actually consume — sampling 20 clinics costs cents
- Line-item billing inside the Apify Console — no surprises
- No monthly minimums, no annual commits, no per-seat fees
- Free to evaluate — start with `maxListings: 20` for a fraction of a cent
- Multi-country, multi-category runs cost proportionally; no penalty for breadth

***

### Changelog

| Version | Date | Notes |
|---|---|---|
| 1.1.0 | 2026-05 | Deep detail-page enrichment — `reviews[]` (individual testimonials with patient name, **origin country**, verification method, date, treatment, full text), `email`, `website`, `latitude`, `longitude`, `postalCode`, `foundingDate`, `paymentMethods`, `currenciesAccepted`, `languages`, `credentials`, `socialLinks`, `ratingScale`. Hybrid extractor: comprehensive JSON-LD `MedicalClinic` harvest + live DOM evaluator via `page.evaluate` + smart author parser. Verified live on Metropolmed Istanbul (13 testimonials, 5 patient-origin countries). |
| 1.0.0 | 2026-05 | Initial public release — Playwright + Chrome engine, multi-pattern listing parser, JSON-LD profile enrichment, residential-proxy rotation, multi-currency price parsing, pay-per-event pricing |

***

### Keywords

WhatClinic scraper · WhatClinic.com data · WhatClinic.com scraper · medical clinic directory scraper · dental clinic data API · medical tourism clinic data · clinic price scraper · healthcare directory extractor · global clinic listings · WhatClinic ServiceScore extractor · hair transplant clinic scraper · dental implant price scraper · cosmetic surgery clinic data · IVF clinic directory scraper · LASIK clinic data · weight loss clinic scraper · physiotherapy clinic directory · skin care clinic data · medical tourism lead generation · clinic comparison data feed · Istanbul hair transplant clinic data · Antalya hair transplant scraper · Bangkok cosmetic surgery clinics · Budapest dental clinic scraper · Mexico City dental data · Mumbai IVF clinic scraper · Warsaw dental clinic data · Dubai eye surgery clinic data · London dental clinic data · Apify medical clinic actor · clinic reviews scraper · clinic pricing benchmark data · private healthcare directory API · global dental price index · medical tourism agency data feed · clinic verification data · clinic lead list for medical devices · clinic SaaS sales lead data · insurance provider network audit data · healthcare M\&A clinic supply data · dental tourism price comparison API · WhatClinic Outstanding clinics data · WhatClinic awards data feed

***

### Support

- **Bug reports** — open an issue on the Apify Store page for this actor
- **Feature requests** — same place; please describe your use case so we can prioritise correctly
- **Direct contact** — through the Apify developer profile (`haketa`)
- **Custom extractions** — need a specific country, vertical or schema variant? Reach out and we can scope it

If this actor saves you days of scraper engineering, a **5-star rating** on the Apify Store helps other medical-tourism, clinic-tech and healthcare-data teams find it. Thank you!

### 📅 Changelog & Maintenance

**Last updated:** 2026-07-02 — Actor verified and maintained. Data pipeline tested for quality, structure and freshness; selectors/endpoints confirmed against the live site.

# Actor input Schema

## `categories` (type: `array`):

Pick one or more treatment areas to scrape. Leave empty to include a mix of all popular treatments.

## `countries` (type: `array`):

Pick one or more countries to search. Leave empty and the scraper will sample the top medical-tourism destinations automatically.

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

Optional — narrow a search to specific cities. Leave empty to cover the whole country (recommended). City paths follow WhatClinic's URL format, e.g. for Turkey: istanbul-province/istanbul.

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

Optional power-user override. Paste WhatClinic.com listing or clinic profile URLs directly and they will be scraped as-is (bypasses the menus above).

## `minServiceScore` (type: `string`):

Only keep clinics whose WhatClinic ServiceScore meets your quality bar. Choose No filter to keep every clinic.

## `scrapeDetails` (type: `boolean`):

Turn on to open each clinic's profile page for richer data: full address, opening hours, treatments, prices, staff, reviews and description. Slower but much more complete.

## `maxListings` (type: `integer`):

Safety cap on the total number of clinics per run. Set 0 for unlimited.

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

How many result pages to load per treatment × country combination (about 15-20 clinics per page). Set 0 for unlimited.

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

Proxy settings used to reach WhatClinic reliably. Residential proxy is recommended for larger runs.

## `requestDelay` (type: `integer`):

Pause between page loads, in milliseconds. Higher values are gentler and more reliable.

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

How many pages to load in parallel. Keep low (1-3) for the most reliable results.

## Actor input object example

```json
{
  "categories": [
    "hair-loss"
  ],
  "countries": [
    "turkey"
  ],
  "cities": [],
  "startUrls": [],
  "minServiceScore": "0",
  "scrapeDetails": false,
  "maxListings": 100,
  "maxPages": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  },
  "requestDelay": 1000,
  "maxConcurrency": 1
}
```

# Actor output Schema

## `dataset` (type: `string`):

Open to view, filter and export all scraped results from this run (JSON, CSV, Excel).

# 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 = {
    "categories": [
        "hair-loss"
    ],
    "countries": [
        "turkey"
    ],
    "cities": [],
    "startUrls": [],
    "maxListings": 100,
    "maxPages": 5,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/whatclinic-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 = {
    "categories": ["hair-loss"],
    "countries": ["turkey"],
    "cities": [],
    "startUrls": [],
    "maxListings": 100,
    "maxPages": 5,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/whatclinic-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 '{
  "categories": [
    "hair-loss"
  ],
  "countries": [
    "turkey"
  ],
  "cities": [],
  "startUrls": [],
  "maxListings": 100,
  "maxPages": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call haketa/whatclinic-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/whatclinic-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/WGe1WFTXQTDNv4Dl7/builds/GbRT1yXi5L4ptaxBo/openapi.json
