# Healthgrades Scraper - Doctors, NPI, Insurance & Reviews (`s-r/healthgrades-scraper`) Actor

Export US doctors from Healthgrades by specialty and city, state or URL: name, specialty, NPI, practice address, phone, rating, review counts, accepted insurers and optional patient reviews. For healthcare marketing, lead lists and reputation analysis.

- **URL**: https://apify.com/s-r/healthgrades-scraper.md
- **Developed by:** [SR](https://apify.com/s-r) (community)
- **Categories:** Lead generation, Marketing, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 providers

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Healthgrades Scraper

Healthgrades Scraper collects public US doctor profiles and optional patient reviews from Healthgrades for healthcare marketing, lead lists and reputation analysis. Search by specialty and location, or supply directory and provider profile URLs, then export the results as structured dataset rows.

Use the data to map a local healthcare market, compare public reputation signals, identify practices that accept particular insurers, or match provider records through their National Provider Identifier (NPI). Each provider row includes the Healthgrades profile URL so you can return to the source and check the current information.

### How to scrape Healthgrades without code

1. Open the actor and enter a specialty such as `Dermatology` and a location such as `Chicago, IL`, or paste one or more Healthgrades search, directory or profile URLs into `startUrls`.
2. Set `maxItems` to the number of providers you need. Leave `includeReviews` off for a provider list, or switch it on and choose `maxReviewsPerPlace` to add patient reviews.
3. Start the run. Providers appear in the dataset as they are collected, each followed by its reviews.
4. Export the dataset as CSV, Excel or JSON, or read it through the Apify API from your own code, a spreadsheet integration or a scheduled task.

### Healthgrades Scraper input

Start with a specialty and a location. The following search was used to collect the example output:

```json
{
  "specialty": "Dermatology",
  "location": "Chicago, IL",
  "maxItems": 45,
  "includeReviews": true
}
```

`specialty` accepts a specialty, provider name or condition. `searchQuery` is an alias for that field. If you provide both fields, `specialty` takes precedence. `location` accepts a US city and state, a five digit ZIP code, a state abbreviation or a full state name. A state input searches the whole state. A city search uses the source's default radius of five miles unless you set `radiusMiles`.

For a wider search, set `radiusMiles` to an integer between 1 and 100. A value of 0 requests a national search. Choose `sortBy` from `bestmatch`, `distance` or `ratings`. These options apply to text searches. Search URLs preserve their own query parameters and ordering.

You can supply up to 20 URLs in `startUrls`. Supported pages include Healthgrades search results, specialty directories and individual physician or provider profiles. For example, the profile fixture comes from `https://www.healthgrades.com/physician/dr-anthony-rizzo-xp8bc`. When URLs are supplied, they take precedence over the text search fields. Providers are deduplicated across the supplied pages.

`maxItems` limits the number of unique providers per search or directory, from 1 to 1,980. It defaults to 20. Reviews do not consume this provider limit. A profile URL supplies one provider. Large searches continue automatically within an Apify run; you do not need to manage the continuation cursor yourself.

### Output and exported fields

The dataset contains two kinds of rows. `record_type` and `_type` identify a row as `place` or `review`. Both types carry `source`, `platform`, `fetched_at` and `place_id`. Reviews appear immediately after their provider, which makes the exported dataset easy to inspect and join.

Provider rows include the name, NPI, primary specialty, profile URL, practice address, city, state, postal code, coordinates and telephone where the source displays them. Additional fields include accepted insurers, age, gender, years of experience, acceptance of new patients, telehealth availability, profile image and practice locations. Some fields can be absent or null because the public page does not display them. The scraper respects address and telephone suppression in the source results.

`rating` is the displayed average star score. `ratings_count` counts all star ratings, while `reviews_count` counts written reviews. These measures serve different purposes and should be kept separate in your analysis. An unrated provider has a null rating, which avoids presenting a missing score as a zero star review.

Set `includeReviews` to true to collect written reviews as separate rows. `maxReviewsPerPlace` controls the number returned for each provider, from 1 to 20. Review rows include the review ID, provider ID, provider name and URL, star rating, original text, publication date and helpful count. A title or author name appears when the source supplies one. Profile URLs can also provide a public provider reply when available.

#### Example Healthgrades doctor row

This is the first provider row from the `Dermatology` / `Chicago, IL` search, exactly as the actor returned it:

```json
{
  "_type": "place",
  "record_type": "place",
  "source": "healthgrades-scraper",
  "platform": "healthgrades",
  "fetched_at": "2026-10-05T08:42:46.578Z",
  "row_id": "place:YT6R6",
  "place_id": "YT6R6",
  "name": "Dr. Ralph Fiore, DO",
  "url": "https://www.healthgrades.com/physician/dr-ralph-fiore-yt6r6",
  "npi": "1770524043",
  "street": "1411 S Michigan Ave",
  "city": "Chicago",
  "state": "IL",
  "postal_code": "60605",
  "lat": 41.86298,
  "lng": -87.62393,
  "phone": "(312) 942-2195",
  "address": "1411 S Michigan Ave, Chicago, IL 60605",
  "country_code": "US",
  "category": "Dermatology",
  "categories": [
    "Dermatology",
    "Dermatologist"
  ],
  "specialty": "Dermatology",
  "rating": 4.8,
  "ratings_count": 51,
  "reviews_count": 33,
  "gender": "M",
  "age": 51,
  "years_experience": null,
  "insurances": [
    "Aetna",
    "Anthem",
    "Anthem Blue Cross Blue Shield",
    "Blue Cross Blue Shield",
    "CareFirst Blue Cross Blue Shield",
    "Cigna",
    "Curative",
    "First Health",
    "Humana",
    "MultiPlan"
  ],
  "accepts_new_patients": true,
  "telehealth": true,
  "is_patient_favorite": false,
  "distance_miles": 0.9,
  "image_url": "https://photos.healthgrades.com/img/prov/Y/T/6/YT6R6_w90h120_v23544.jpg",
  "about": "Dr. Ralph Fiore II is a board-certified Dermatologist specializing in medical dermatology and surgical dermatology with an emphasis on the detection and treatment of premalignant and malignant conditions of the skin.",
  "practice_locations": [
    {
      "street": "1411 S Michigan Ave",
      "city": "Chicago",
      "state": "IL",
      "postal_code": "60605",
      "lat": 41.86298,
      "lng": -87.62393
    },
    {
      "street": "13401 S Ridgeland Ave",
      "city": "Palos Heights",
      "state": "IL",
      "postal_code": "60463",
      "lat": 41.6481,
      "lng": -87.77699
    },
    {
      "street": "18425 West Creek Dr Ste F",
      "city": "Tinley Park",
      "state": "IL",
      "postal_code": "60477",
      "lat": 41.55622,
      "lng": -87.80044
    },
    {
      "street": "10500 W Loomis Rd Ste 110",
      "city": "Franklin",
      "state": "WI",
      "postal_code": "53132",
      "lat": 42.87986,
      "lng": -88.04972
    }
  ],
  "search_query": "Dermatology",
  "search_location": "Chicago, IL",
  "search_position": 1
}
```

#### Example patient review row

The review rows for that provider follow directly after it. This is the first one:

```json
{
  "_type": "review",
  "record_type": "review",
  "source": "healthgrades-scraper",
  "platform": "healthgrades",
  "fetched_at": "2026-10-05T08:42:46.605Z",
  "row_id": "review:883924cf-c043-4072-a6e9-bd57c80fd2ce",
  "review_id": "883924cf-c043-4072-a6e9-bd57c80fd2ce",
  "place_id": "YT6R6",
  "place_name": "Dr. Ralph Fiore, DO",
  "place_url": "https://www.healthgrades.com/physician/dr-ralph-fiore-yt6r6",
  "rating": 5,
  "text": "Dr. Fiore is very friendly, takes the time to explain everything to you, answers all your questions ",
  "published_at": "2024-07-03T00:00:00Z",
  "likes": 0,
  "title": "Definitely",
  "author_name": "Rose Culhane"
}
```

Download the dataset in JSON, CSV, Excel or another format supported by Apify. Use `place_id` to join a review back to its provider and NPI to match provider records in another healthcare dataset. NPI identifies the provider; it does not identify a particular practice location.

### Use cases for Healthgrades data

- **Healthcare marketing and lead lists.** Build a list of dermatologists, orthopedic surgeons or family physicians in a city or state, with practice address, phone, NPI and the insurers they accept, ready for outreach or territory planning.
- **Reputation monitoring.** Track star ratings, rating counts and the newest written reviews for your own physicians and for competing practices, and see which providers patients mark as favorites.
- **Market and network analysis.** Count providers per specialty and ZIP code, find areas where few doctors accept new patients or offer telehealth, and check which insurance networks are well covered.
- **Data enrichment.** Join Healthgrades ratings and reviews onto an existing provider database through the NPI, so a CRM or analytics table carries the public patient view next to your own records.
- **Research.** Study how ratings, review volume, experience and insurance acceptance vary across specialties and regions.

### Healthgrades Scraper compared with other options

| Option | What you get | Trade-off |
|---|---|---|
| Browsing healthgrades.com by hand | Any profile you open | Slow, no export, no review history across many doctors |
| Healthgrades business products | Tools for practices managing their own listings | Meant for a provider's own profile, not for exporting the directory |
| A self-built Healthgrades scraper | Full control | You maintain parsing, paging and review collection when the site changes |
| Other Healthgrades actors in the Apify Store | Doctor rows, often with NPI | Many cover providers only; check whether reviews, insurers and practice locations are included |
| **This Healthgrades Scraper** | Providers with NPI, insurers, ratings, practice locations and optional patient reviews in one dataset | Limited to what Healthgrades shows publicly: 99 search pages and 20 recent reviews per provider |

### Pricing and free usage

The actor uses separate provider and review events. A provider event corresponds to one delivered `place` row, and a review event corresponds to one delivered `review` row. The current event prices are shown in the actor's pricing tab. There is no scraper start fee, and a run that returns no rows has no result events to charge.

Free users receive up to 10 dataset rows per run, counting providers and reviews together. Your chosen `maxReviewsPerPlace` remains in effect within that total row limit. Because reviews follow their provider, enabling them means fewer providers fit into the free sample. For a provider only sample, leave `includeReviews` disabled. Your Apify spending limit can also stop delivery before the requested provider limit is reached.

### Limits and incomplete searches

Healthgrades exposes at most 99 pages for one search and at most 20 recent written reviews per provider. A profile can show more total written reviews than the scraper can retrieve. The actor reports the provider's displayed total without suggesting that the exported review sample represents its complete history.

For broader coverage, split large searches into cities, ZIP codes or smaller radii. A national search still has the same page limit. Check the run output for `partial` and `warnings` when a source page or optional review request could not be completed. Provider rows remain available when only review collection fails. An unrecognised location produces no matching provider rows instead of returning the source's fallback city.

### Frequently asked questions

#### Can I retrieve every historical review?

The source exposes up to 20 recent written reviews per provider. Increasing `maxReviewsPerPlace` beyond 20 is unsupported. Keep the displayed written review total separate from the number of review rows you export.

#### Can I search an entire state?

Yes. Use a state abbreviation such as `NY`, a full state name or a state specialty directory URL. The same maximum of 99 source pages applies. Split the state into smaller searches when you need coverage beyond that limit.

#### Why are ratings and review counts different?

A person can submit a star rating without a written review. `ratings_count` includes star ratings, and `reviews_count` counts written reviews. Review rows represent the written review sample actually returned by the source.

#### Does this provide private patient records or medical advice?

It collects public provider information and public review text displayed by Healthgrades. The output describes the source's listings and opinions. It does not provide medical advice or determine whether a provider is suitable for an individual patient.

#### Is there an official Healthgrades API?

Healthgrades does not offer a public self-serve API for exporting its doctor directory or patient reviews. This actor works as a Healthgrades API alternative: start it through the Apify API with the same input as above and read the dataset as JSON.

#### Can I export Healthgrades doctors to Excel or CSV?

Yes. Every run stores its rows in an Apify dataset, which you can download as CSV, Excel, JSON, XML or HTML. Filter on `record_type` to separate doctors from reviews.

#### Does the scraper return email addresses?

No. Healthgrades does not show email addresses on provider profiles, so the actor returns the phone number and practice address that the source displays.

# Actor input Schema

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

Specialty, provider name or condition, such as Dermatology. Required with location when startUrls is empty.

## `searchQuery` (type: `string`):

Alias for specialty; specialty takes precedence when both are supplied.

## `location` (type: `string`):

US city and state (Chicago, IL), five-digit ZIP code, state abbreviation or full state name. Required for a text search.

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

Up to 20 Healthgrades search, specialty directory or physician/provider profile URLs. URLs take precedence over the text search.

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

Maximum number of unique providers per search or directory, across all cursor pages. Reviews do not consume this provider limit.

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

Return public written reviews as separate rows immediately after their provider.

## `maxReviewsPerPlace` (type: `integer`):

Maximum written reviews per provider. Healthgrades exposes at most 20 recent written reviews, even when the profile has more.

## `radiusMiles` (type: `integer`):

Search radius in miles (1–100); 0 searches nationally. Omit for the source default of 5 miles. Applies to text searches.

## `sortBy` (type: `string`):

Ordering for text searches. URL searches preserve their filters and sort order.

## `cursor` (type: `string`):

Opaque next_cursor from a previous response. Keep all other inputs unchanged. Apify follows it automatically.

## Actor input object example

```json
{
  "specialty": "Dermatology",
  "location": "Chicago, IL",
  "startUrls": [],
  "maxItems": 20,
  "includeReviews": false,
  "maxReviewsPerPlace": 20,
  "sortBy": "bestmatch"
}
```

# Actor output Schema

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

One row per delivered provider or review.

## `output` (type: `string`):

Counts, warnings and delivery status.

# 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": "Dermatology",
    "location": "Chicago, IL"
};

// Run the Actor and wait for it to finish
const run = await client.actor("s-r/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": "Dermatology",
    "location": "Chicago, IL",
}

# Run the Actor and wait for it to finish
run = client.actor("s-r/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": "Dermatology",
  "location": "Chicago, IL"
}' |
apify call s-r/healthgrades-scraper --silent --output-dataset

```

## MCP server setup

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