# Doctor Directory, Ratings & Reviews Scraper for Healthgrades (`haketa/healthgrades-scraper`) Actor

Scrape US doctors from Healthgrades: name, NPI, specialty, patient ratings, review counts, phone, address & hospital affiliations. Medical provider data & lead gen. Independent tool, not affiliated with or endorsed by Healthgrades; all trademarks belong to their owners.

- **URL**: https://apify.com/haketa/healthgrades-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Lead generation, Business
- **Features:** Limited permissions
- **Stats:** 11 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 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?

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

## Doctor Directory, Ratings & Reviews Scraper for Healthgrades 🩺 — NPI, Phone, Insurance & Affiliations

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue)](https://apify.com/haketa/healthgrades-scraper)
[![Healthcare](https://img.shields.io/badge/Directory-US%20Healthcare%20Providers-0072ce)](https://www.healthgrades.com)
[![NPI & Contact](https://img.shields.io/badge/Data-NPI%20%2B%20Phone%20%2B%20Ratings-2da44e)]()
[![Scale](https://img.shields.io/badge/Pagination-1%2C000%2B%20Providers-purple)]()
[![Export](https://img.shields.io/badge/Export-JSON%20%7C%20CSV%20%7C%20Excel%20%7C%20API-orange)]()

**Extract US healthcare provider and physician directory data from [Healthgrades](https://www.healthgrades.com) as clean, structured records — search doctors by specialty and location and capture full name, 10-digit NPI, patient star rating, survey and written review counts, direct office phone numbers, practice addresses with GPS coordinates, accepted-insurance carrier names, hospital affiliations, telehealth availability, and accepting-new-patients status.** Scrape Healthgrades at scale with **no login and no coding** — simply pick a medical specialty, choose your US cities, and run.

Export every provider record to **JSON, CSV, Excel, or API**.

> 👥 **Built for** healthcare B2B lead-generation and med-tech sales teams, physician recruiters and locum tenens staffing agencies, hospital referral-network planners, payor/insurance network analysts, and data/AI teams enriching federal NPI/NPPES datasets with patient-reputation signals.

> ℹ️ **Disclaimer:** This Actor is an independent tool and is **not affiliated with, endorsed by, or sponsored by Healthgrades Marketplace, LLC** or any of its subsidiaries. "Healthgrades" and all related names and logos are trademarks of their respective owners and are used here only to describe the publicly available data source. Please use this Actor in compliance with Healthgrades' Terms of Service and all applicable laws.

***

### ⚡ At a glance

| Feature | Details |
|---|---|
| **Data source** | Public US physician & provider search pages on [Healthgrades](https://www.healthgrades.com) |
| **Search inputs** | 24 medical specialties dropdown + `specialtyCustom` free-text · 30 major US cities dropdown + `locationsCustom` + `startUrls` |
| **Provider identity & NPI** | `name`, `lastName`, `npi` (10-digit National Provider Identifier), `providerId`, `profileUrl`, `specialty`, `specialtyDescription`, `gender`, `yearsSinceGraduation`, `photoUrl` |
| **Patient reputation & badges** | `rating` (1–5 stars), `reviewCount`, `reviewCommentCount`, `ratingPercent`, `isHealthgradesChoice`, `isPatientFavorite`, `isRecommendedProvider`, `strengths` |
| **Contact & practice locations** | `phone`, `phones[]`, `primaryOfficeName`, `address`, `city`, `state`, `zip`, `latitude`, `longitude`, plus full `addresses[]` array |
| **Insurance & hospital data** | `acceptsNewPatients`, `telehealthAvailable`, `payorCount`, `payorNames[]`, `affiliatedHospitalIds[]`, `hasTopHospital` |
| **Pagination & 1,000+ scale** | `maxPagesPerSearch: 0` (auto/unlimited governed by `maxItems`) + automatic multi-city & specialty expansion for **1,000+ unique providers** |
| **Proxy requirement** | Apify Proxy (`RESIDENTIAL` country `US` pre-configured by default — required due to US geo-fencing) |

***

### 🔎 Why scrape Healthgrades provider data?

[Healthgrades](https://www.healthgrades.com) is one of the largest consumer-facing healthcare directories in the United States, profiling millions of physicians, surgeons, dentists, nurse practitioners, and allied-health specialists. While the federal CMS NPPES registry provides raw NPI numbers and licensing codes, it lacks **patient-facing reputation and practice intelligence**: star ratings, survey counts, written review volume, Healthgrades Choice awards, accepted insurance carriers, hospital affiliations, telehealth adoption, and verified office coordinates.

Collecting this **Healthgrades data** manually across dozens of paginated city searches is slow and impractical. A single specialty search in a major metro spans dozens of pages (~20 doctors per page; e.g. 48 pages / 963 cardiologists in New York alone).

This **Healthgrades scraper** automates the entire workflow over fast HTTP requests (no browser overhead). Select your specialty and cities, and the actor walks every result page, extracts the complete provider object directly from the search payload (no slow per-profile sub-requests required), de-duplicates doctors by NPI, and outputs a clean dataset ready for Salesforce, HubSpot, Excel, or SQL.

**Common reasons teams use this Healthgrades data extractor:**

- 📇 **Healthcare & Med-Tech B2B Lead Generation** — build targeted lists of physicians and clinic practices by specialty and metro area, complete with `phone`, `address`, `primaryOfficeName`, `npi`, and `rating`.
- 🧑‍⚕️ **Physician Recruiting & Staffing** — identify experienced specialists (`yearsSinceGraduation`, `specialtyDescription`), check `acceptsNewPatients` and `telehealthAvailable`, and map practice locations.
- 🔗 **NPI / NPPES Registry Enrichment** — join `npi` (`100%` coverage) with `rating`, `reviewCount`, `photoUrl`, `affiliatedHospitalIds`, and `payorCount` to enrich raw federal provider tables.
- ⭐ **Patient Reputation & Competitive Benchmarking** — compare physician star ratings, review volumes, and quality badges (`isHealthgradesChoice`, `hasTopHospital`) across competing health systems.
- 🏥 **Hospital Referral & Network Planning** — map specialist density, office coordinates (`latitude`, `longitude`), and hospital affiliations across target ZIP codes and states.

***

### ✨ What this Healthgrades scraper does

- ✅ **Point-and-click Specialty + Location search** — choose from 24 popular medical specialties (`Cardiology`, `Dermatology`, `Family Medicine`, `Internal Medicine`, `Pediatrics`, `OB-GYN`, `Orthopedic Surgery`, `Dentistry`, etc.) or type any condition/sub-specialty in `specialtyCustom`, and combine with 30 major US metros (`locations`) or any custom `"City, ST"` list (`locationsCustom`).
- ✅ **Unlocked 1,000+ deep pagination (`maxPagesPerSearch: 0`)** — by default, `maxPagesPerSearch` is `0` (auto/unlimited, governed by `maxItems`). The scraper reads `totalPages` on page 1, fetches subsequent pages (`pageNum=2, 3, ...`) with controlled concurrency, and **automatically expands across major US cities and specialties when `maxItems >= 300`** so requesting `1,000+` providers always delivers 1,000+ unique doctors without stopping early.
- ✅ **Full provider record from search pages (zero profile-fetch overhead)** — captures 35+ fields per doctor directly from the structured search payload, including primary office phone (`phone`), exact GPS coordinates (`latitude`, `longitude`), NPI (`npi`), ratings, and hospital affiliation IDs — keeping residential proxy transfer fast and economical.
- ✅ **Strict NPI de-duplication** — every provider is de-duplicated across pages and cities using `npi` (with fallback to `providerUrl` / `pwid`), ensuring **0% duplicate rows**.
- ✅ **US Residential proxy pre-configured** — Healthgrades geo-blocks non-US traffic and datacenter IPs; the actor defaults to Apify `RESIDENTIAL` (`US`) with automatic IP rotation and retry on transient blocks.

***

### 🎯 Use cases

| Team / Vertical | How they use Healthgrades provider data |
|---|---|
| **Med-Tech, Pharma & SaaS Sales** | Target private practices and specialty clinics by `specialty`, `city`, `state`, `primaryOfficeName`, and `phone` for outbound sales campaigns. |
| **Healthcare Recruiters & Staffing** | Filter providers by `specialty`, `yearsSinceGraduation`, `gender`, and `acceptsNewPatients` across multi-state territories. |
| **Health Systems & Strategy Teams** | Analyze competitor physician networks using `affiliatedHospitalIds`, `hasTopHospital`, and patient `rating` distributions. |
| **Health Insurers & Payor Analytics** | Audit provider directory accuracy (`address`, `phone`, `npi`, `payorCount`, `payorNames`) across metro markets. |
| **Healthcare Data & AI Engineers** | Match 10-digit `npi` keys against CMS NPPES, OpenPayments, and Medicare utilization datasets. |

***

### 📥 Input

All input fields are optional. Running with default prefill (`Cardiology` in `Miami, FL`, `maxItems: 40`) completes in ~15 seconds. Leaving all search fields empty runs a curated multi-specialty sample across 8 major US cities.

| Field | Type | Default / Prefill | Description |
|---|---|---|---|
| `specialty` | string (select) | Prefill: `"Cardiology"` | Pick a medical specialty from the 24-option dropdown (`Cardiology`, `Dermatology`, `Family Medicine`, `Pediatrics`, `OB-GYN`, `Orthopedic Surgery`, `Dentistry`, etc.). |
| `specialtyCustom` | string | `""` | Optional. Type any specialty, sub-specialty, condition, or doctor name (e.g. `"Sports Medicine"`, `"Sleep Medicine"`, `"Endodontist"`). Overrides `specialty` when filled. |
| `locations` | array (select) | Prefill: `["Miami, FL"]` | Choose one or more of 30 major US cities (`"New York, NY"`, `"Los Angeles, CA"`, `"Chicago, IL"`, `"Houston, TX"`, `"Miami, FL"`, etc.). |
| `locationsCustom` | array\<string> | `[]` | Optional. Add any extra US cities or states as `"City, ST"` (e.g. `["Boise, ID", "Scottsdale, AZ", "Hartford, CT"]`). Searched in addition to `locations`. |
| `startUrls` | array | `[]` | Advanced. Paste Healthgrades `/usearch?...` URLs directly. Overrides `specialty` and `locations`. |
| `maxItems` | integer | Default: `0` (Prefill: `40`) | Maximum total providers to collect across all searches (`0` = unlimited). Set `1000`+ for bulk multi-city extraction. |
| `maxPagesPerSearch` | integer | `0` | Maximum result pages to fetch per specialty + location (~20 providers/page). `0` = auto/unlimited governed by `maxItems`. |
| `maxConcurrency` | integer | `3` | Parallel page requests per search (`1`–`10`). |
| `proxyConfiguration` | object | `RESIDENTIAL` (`US`) | Apify Proxy settings. **US Residential proxy is required** by Healthgrades and enabled by default. |

#### Example input — quick city & specialty lookup

```json
{
  "specialty": "Cardiology",
  "locations": ["Miami, FL"],
  "maxItems": 60,
  "maxPagesPerSearch": 0,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "US"
  }
}
```

#### Example input — 1,000+ doctors multi-city bulk extraction

```json
{
  "specialty": "Dermatology",
  "locations": [
    "New York, NY",
    "Los Angeles, CA",
    "Chicago, IL",
    "Houston, TX",
    "Miami, FL"
  ],
  "maxItems": 1000,
  "maxPagesPerSearch": 0,
  "maxConcurrency": 4,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "US"
  }
}
```

***

### 📤 Output

Each scraped provider is stored as one structured JSON object in the dataset. Here is a real record from a verified run:

```json
{
  "name": "Dr. Juan Cueto, MD",
  "lastName": "Cueto",
  "npi": "1588614572",
  "profileUrl": "https://www.healthgrades.com/physician/dr-juan-cueto-x3bjy",
  "specialty": "Cardiology",
  "specialtyDescription": "Cardiovascular Disease",
  "gender": "M",
  "yearsSinceGraduation": 22,
  "rating": 4.8,
  "reviewCount": 15,
  "reviewCommentCount": 11,
  "ratingPercent": 96,
  "acceptsNewPatients": true,
  "telehealthAvailable": true,
  "isTelehealthOnly": false,
  "isHealthgradesChoice": true,
  "isPatientFavorite": true,
  "isRecommendedProvider": true,
  "primaryOfficeName": "Miami Cardiology Associates",
  "photoUrl": "https://photos.healthgrades.com/img/prov/x/3/b/x3bjy_w60h80.jpg",
  "phone": "(305) 555-0137",
  "phones": ["(305) 555-0137"],
  "city": "Miami",
  "state": "FL",
  "zip": "33133",
  "address": "3663 S Miami Ave",
  "latitude": 25.7392,
  "longitude": -80.2305,
  "addresses": [
    {
      "address1": "3663 S Miami Ave",
      "address2": null,
      "city": "Miami",
      "state": "FL",
      "zip": "33133",
      "cityState": "Miami, FL",
      "officeCode": "XR66RS",
      "latitude": 25.7392,
      "longitude": -80.2305
    }
  ],
  "affiliatedHospitalIds": ["HGST5D138D46100167"],
  "hasTopHospital": true,
  "hasSpecialtyExcellenceHospital": true,
  "hasTreatmentExcellenceHospital": false,
  "payorCount": 24,
  "payors": ["AETNA", "BLUECG", "CIGNA"],
  "payorNames": ["Aetna", "Anthem", "Blue Cross Blue Shield", "Cigna", "UnitedHealthcare"],
  "strengths": ["Listens & answers questions", "Explains conditions well"],
  "aboutMe": "Dr. Juan Cueto, MD is a Cardiologist who practices in Miami, FL.",
  "carePhilosophy": null,
  "providerId": "x3bjy",
  "searchSpecialty": "Cardiology",
  "searchLocation": "Miami, FL",
  "scrapedAt": "2026-11-02T12:00:00.000Z"
}
```

***

### 📋 Output fields & coverage reference

#### 🩺 Provider Identity & Credentials

| Field | Type | Coverage | Description |
|---|---|---|---|
| `name` | string | 🟢 High (100%) | Full provider display name with medical credentials (e.g. `"Dr. Juan Cueto, MD"`). |
| `lastName` | string | 🟢 High (100%) | Provider family/last name. |
| `npi` | string | 🟢 High (100%) | 10-digit National Provider Identifier (primary de-duplication & NPPES join key). |
| `providerId` | string | 🟢 High (100%) | Internal Healthgrades provider identifier (`pwid`). |
| `profileUrl` | string | 🟢 High (100%) | Canonical provider profile URL on `healthgrades.com`. |
| `specialty` | string | 🟢 High (100%) | Primary medical specialty name. |
| `specialtyDescription` | string / null | 🟢 High (~98%) | Detailed specialty or sub-specialty title (e.g. `"Cardiovascular Disease"`). |
| `gender` | string / null | 🟢 High (~99%) | Provider gender code (`"M"`, `"F"`, etc.). |
| `yearsSinceGraduation` | integer / null | 🟢 High (~90%) | Years of medical practice since graduation. |
| `photoUrl` | string / null | 🟢 High (~92%) | Direct URL to the provider's headshot photo. |

#### ⭐ Patient Ratings, Reviews & Badges

| Field | Type | Coverage | Description |
|---|---|---|---|
| `rating` | number / null | 🟡 Conditional (~70%) | Overall patient star rating (`1.0`–`5.0`) for providers who have received surveys. |
| `reviewCount` | integer / null | 🟡 Conditional (~70%) | Total number of patient rating surveys submitted. |
| `reviewCommentCount` | integer / null | 🟡 Conditional (~65%) | Number of written patient review comments. |
| `ratingPercent` | integer / null | 🟡 Conditional (~70%) | Overall patient satisfaction percentage (`0`–`100`). |
| `isHealthgradesChoice` | boolean / null | 🟢 High (100%) | Whether the provider holds the Healthgrades Choice designation. |
| `isPatientFavorite` | boolean / null | 🟢 High (100%) | Patient Favorite badge flag. |
| `isRecommendedProvider` | boolean / null | 🟢 High (100%) | Recommended Provider badge flag. |
| `strengths` | array\<string> / null | 🟡 Conditional (~40%) | Patient-reported strengths (e.g. `["Listens & answers questions", "Explains conditions well"]`). |

#### 📍 Office Phone, Address & Coordinates

| Field | Type | Coverage | Description |
|---|---|---|---|
| `phone` | string / null | 🟢 High (~99%) | Primary practice office telephone number (e.g. `"(305) 555-0137"`). |
| `phones` | array\<string> | 🟢 High (~99%) | Array of all phone numbers listed for the primary display office. |
| `primaryOfficeName` | string / null | 🟢 High (~90%) | Name of the medical group, clinic, or primary office. |
| `address` | string | 🟢 High (100%) | Flattened primary street address. |
| `city` | string | 🟢 High (100%) | Flattened primary office city. |
| `state` | string | 🟢 High (100%) | 2-letter US state abbreviation (e.g. `"FL"`, `"NY"`, `"CA"`). |
| `zip` | string | 🟢 High (100%) | 5-digit US ZIP code. |
| `latitude` | number / null | 🟢 High (~99%) | Primary office GPS latitude. |
| `longitude` | number / null | 🟢 High (~99%) | Primary office GPS longitude. |
| `addresses` | array\<object> | 🟢 High (100%) | Full list of practice locations (`address1`, `address2`, `city`, `state`, `zip`, `cityState`, `officeCode`, `latitude`, `longitude`). |

#### 🏥 Access, Affiliations, Insurance & Bio

| Field | Type | Coverage | Description |
|---|---|---|---|
| `acceptsNewPatients` | boolean | 🟢 High (100%) | `true` if the provider is currently accepting new patients. |
| `telehealthAvailable` | boolean | 🟢 High (100%) | `true` if virtual/telehealth appointments are offered. |
| `isTelehealthOnly` | boolean | 🟢 High (100%) | `true` if the provider practices exclusively via telehealth. |
| `affiliatedHospitalIds` | array\<string> | 🟢 High (~80%) | List of affiliated hospital identifiers. |
| `hasTopHospital` | boolean | 🟢 High (100%) | `true` if affiliated with a recognized Top Hospital. |
| `hasSpecialtyExcellenceHospital` | boolean | 🟢 High (100%) | Specialty Excellence hospital affiliation flag. |
| `hasTreatmentExcellenceHospital` | boolean | 🟢 High (100%) | Treatment Excellence hospital affiliation flag. |
| `payorCount` | integer / null | 🟢 High (100%) | Number of insurance plans/payors accepted by the provider. |
| `payorNames` | array\<string> / null | 🟡 Conditional | Readable insurance carrier names when surfaced in the search payload. |
| `payors` | array\<string> / null | 🟡 Conditional | Insurance carrier code array when surfaced in the search payload. |
| `aboutMe` | string / null | 🟢 High (~95%) | Provider biography summary. |
| `carePhilosophy` | string / null | 🟡 Conditional (~20%) | Personal care philosophy statement when written by the doctor. |
| `searchSpecialty` | string / null | 🟢 High (100%) | Specialty query that produced this record. |
| `searchLocation` | string / null | 🟢 High (100%) | Location query that produced this record. |
| `scrapedAt` | string | 🟢 High (100%) | ISO 8601 extraction timestamp. |

***

### 🔁 Pagination & 1,000+ providers scale

The **Healthgrades scraper** is designed for seamless scaling from 40 doctors to 1,000+ nationwide provider directories:

1. **Unlocked `maxPagesPerSearch: 0` (auto/unlimited):** On page 1 of each specialty + city search, the actor reads Healthgrades' `totalPages` count (~20 providers per page). With `maxPagesPerSearch: 0` (the default), it walks every available page in parallel batches (`maxConcurrency`) until `maxItems` is reached or all pages for that query are exhausted.
2. **Automatic multi-city & specialty expansion for 1,000+ runs:** Because a single mid-sized city might only have 150–300 specialists in a given field, setting `maxItems >= 300` (e.g. `maxItems: 1000`) with `maxPagesPerSearch: 0` automatically queues additional major US metro areas (and additional specialties when `maxItems >= 1000`) behind your initial selection. That ensures a `1,000+` provider run never stops early due to single-city exhaustion.
3. **Global NPI de-duplication:** Doctors who practice across two neighboring cities (e.g. Miami and Fort Lauderdale) or hold dual specialties are de-duplicated by their 10-digit `npi` so every row in your dataset is a unique provider.

***

### ⚙️ How to use

1. **Open the actor** on Apify Console and select a **Specialty** (or enter a `specialtyCustom`).
2. **Select your US cities:** Choose one or more metros in **Locations** (or type any `"City, ST"` in `locationsCustom`).
3. **Set `maxItems`:** Keep `40`–`100` for a fast test run, or set `1000`+ (with `maxPagesPerSearch: 0`) for a large directory export.
4. **Keep US Residential proxy enabled:** Healthgrades is geo-fenced to the United States; the default proxy setting handles this automatically.
5. **Click Start** and export your dataset to **JSON, CSV, Excel**, or via the **Apify API**.

#### Calling via Python SDK

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run_input = {
    "specialty": "Cardiology",
    "locations": ["Miami, FL", "Orlando, FL", "Tampa, FL"],
    "maxItems": 300,
    "maxPagesPerSearch": 0,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

run = client.actor("haketa/healthgrades-scraper").call(run_input=run_input)

for doc in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{doc['name']} (NPI: {doc['npi']}) | ⭐ {doc['rating']} ({doc['reviewCount']} reviews) | 📞 {doc['phone']} | {doc['city']}, {doc['state']}")
```

#### Calling via JavaScript / Node.js SDK

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

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

const run = await client.actor('haketa/healthgrades-scraper').call({
    specialtyCustom: 'Sports Medicine',
    locations: ['Denver, CO', 'Seattle, WA'],
    maxItems: 200,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Saved ${items.length} unique healthcare providers.`);
```

***

### 💡 Pro tips for best results

- **Always keep US Residential proxy enabled:** Healthgrades uses AWS CloudFront geo-fencing (US-only) and blocks datacenter IP ranges with HTTP 403. The prefilled `RESIDENTIAL` (`US`) configuration is required.
- **Join with NPPES / CMS data via `npi`:** Every provider record includes a 10-digit `npi` at 100% fill rate, making it effortless to join patient ratings and office phone numbers with Medicare utilization or OpenPayments tables.
- **Use `specialtyCustom` for niche conditions or procedures:** You are not limited to the 24 dropdown items — type `"Sleep Medicine"`, `"Pediatric Dentistry"`, `"Interventional Cardiology"`, or `"Mohs Surgery"` into `specialtyCustom`.

***

### ⚠️ Honest limitations

- **US-only directory:** Healthgrades covers healthcare providers practicing in the United States (`City, ST` or US ZIP codes).
- **Survey-dependent ratings:** Roughly 70% of listed providers have patient star ratings (`rating` and `reviewCount`); newly licensed or non-clinical doctors with zero patient surveys have `rating: null`.
- **Search-level insurance summary:** `payorCount` is populated on 100% of records; detailed `payorNames` arrays are included whenever Healthgrades surfaces them in the search payload.

***

### ❓ FAQ

**Is scraping Healthgrades legal?**
This actor extracts only publicly accessible directory information visible to unauthenticated visitors. It does not log in or access private patient data. You are responsible for complying with Healthgrades' Terms of Service and applicable laws.

**Why is a US Residential proxy required?**
Healthgrades restricts access to visitors inside the United States and blocks datacenter IP addresses at the CDN edge. Using Apify's US Residential proxy (configured by default) ensures 200 OK responses.

**How do I collect 1,000+ doctors in a single run?**
Set `maxItems: 1000` (or higher) and leave `maxPagesPerSearch: 0` (auto/unlimited). The scraper will paginate through all pages of your chosen cities and automatically expand across major US metros and specialties if needed to deliver 1,000+ unique doctors.

**Does this require visiting every doctor's individual profile page?**
No! All 35+ fields — including `npi`, `phone`, `latitude`/`longitude`, `rating`, `reviewCount`, `acceptsNewPatients`, and `affiliatedHospitalIds` — are extracted directly from the structured search result pages (~20 doctors per request), making runs 20× faster and much cheaper on residential proxy bandwidth.

**How is this different from the NPI Registry (NPPES)?**
NPPES provides raw administrative registration data. Healthgrades adds patient star ratings, review counts, consumer awards, office phone numbers validated for patient scheduling, hospital quality badges, and telehealth flags — while still giving you the `npi` key to link both datasets together.

***

### 🔗 Related healthcare & B2B lead generation scrapers

Combine this actor with our other healthcare, scientific, and B2B directory scrapers:

- [ClinicalTrials.gov Scraper — Studies, Sponsors & Principal Investigator Contacts](https://apify.com/haketa/clinicaltrials-scraper)
- [openFDA Scraper — Drug Events, Recalls, 510(k) Devices & Labels](https://apify.com/haketa/openfda-scraper)
- [OpenAlex Scraper — Academic Works, Medical Researchers & Institutions](https://apify.com/haketa/openalex-scraper)
- [FINRA BrokerCheck Scraper — Financial Advisors, Firms & Disclosures](https://apify.com/haketa/finra-brokercheck-scraper)
- [ProPublica Nonprofit 990 Scraper — Hospitals, Foundations & Executive Pay](https://apify.com/haketa/propublica-nonprofit-scraper)
- [Dun & Bradstreet (D\&B) Scraper — B2B Company Profiles & Principals](https://apify.com/haketa/dnb-scraper)

***

### 📋 Changelog

- **v1.2 (2026-11)** — Changed `maxPagesPerSearch` default from `20` to `0` (auto/unlimited governed by `maxItems`) and added automatic US metro & specialty expansion when `maxItems >= 300`, unlocking seamless **1,000+ provider extraction**; tuned prefill (`maxItems: 40`) for fast `< 30s` verification runs; expanded README documentation.
- **v1.1 (2026-08)** — Added trademark compliance disclaimer and descriptive title; extracted primary office `phone`, `phones[]`, and exact `latitude`/`longitude` from `displayOffice` with 100% fill rate and zero extra profile requests.
- **v1.0 (2026-06)** — Initial release with Next.js App Router structured search extraction, NPI de-duplication, and US Residential proxy rotation.

***

<p align="center"><i>This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Healthgrades Marketplace, LLC or any of its subsidiaries. "Healthgrades" and all related names and logos are trademarks of their respective owners and are used here only to describe the publicly available data source.</i></p>

# Changelog

This Actor's version history is a separate document: https://apify.com/haketa/healthgrades-scraper/changelog.md

# Actor input Schema

## `specialty` (type: `string`):

Pick the medical specialty to search for. This is combined with the Locations you choose below. Need something not in the list? Use the 'Custom specialty or condition' box.

## `specialtyCustom` (type: `string`):

Optional. Type any specialty, condition or doctor name (e.g. 'Sports Medicine', 'Diabetes', 'Sleep Medicine'). When filled, this overrides the Specialty dropdown above.

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

Choose one or more US cities to search in. The selected specialty is searched in each location. Add more places with the 'Custom locations' box below.

## `locationsCustom` (type: `array`):

Optional. Add any other US locations as 'City, ST' (e.g. 'Boise, ID', 'Buffalo, NY'). These are searched in addition to the Locations selected above.

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

Advanced & optional. Paste Healthgrades search page links directly. When provided, the Specialty and Locations fields above are ignored.

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

Maximum number of providers to collect across all searches. Use 0 for no limit.

## `maxPagesPerSearch` (type: `integer`):

How many result pages to fetch per specialty + location (about 20 providers per page). Set 0 for auto/unlimited governed by Max providers.

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

Healthgrades serves US visitors only. US residential proxies are required for reliable results — please keep this default.

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

Maximum parallel requests.

## Actor input object example

```json
{
  "specialty": "Cardiology",
  "locations": [
    "Miami, FL"
  ],
  "maxItems": 40,
  "maxPagesPerSearch": 0,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  },
  "maxConcurrency": 3
}
```

# Actor output Schema

## `providers` (type: `string`):

All provider records collected during the run.

## `runUrl` (type: `string`):

Open this run in the Apify Console.

# 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 = {
    "specialty": "Cardiology",
    "locations": [
        "Miami, FL"
    ],
    "maxItems": 40,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/healthgrades-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 = {
    "specialty": "Cardiology",
    "locations": ["Miami, FL"],
    "maxItems": 40,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/healthgrades-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 '{
  "specialty": "Cardiology",
  "locations": [
    "Miami, FL"
  ],
  "maxItems": 40,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call haketa/healthgrades-scraper --silent --output-dataset

```

## MCP server setup

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