# Vitals.com Scraper 🏥 (`shahidirfan/vitals-com-scraper`) Actor

Unlock valuable healthcare data! Instantly extract detailed doctor profiles, patient reviews, and facility info from Vitals.com. Perfect for medical market research, lead generation, and competitive analysis. Get accurate, structured data efficiently today.

- **URL**: https://apify.com/shahidirfan/vitals-com-scraper.md
- **Developed by:** [Shahid Irfan](https://apify.com/shahidirfan) (community)
- **Categories:** Developer tools, Automation, Other
- **Features:** Limited permissions
- **Stats:** 20 total users, 3 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.80 / 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

### What does Vitals.com Physician Scraper do?

Vitals.com Physician Scraper collects structured physician directory data from Vitals.com. Search by medical specialty and location, or provide a direct Vitals.com directory URL, then save provider names, specialties, locations, ratings, review counts, experience, profile links, and other public listing details to an Apify Dataset.

The Actor is useful for healthcare market research, provider directory projects, physician recruitment, insurance network analysis, and location-based medical data collection. It supports pagination, result limits, duplicate prevention, and optional Apify Proxy configuration for repeat or larger runs.

### Why use Vitals.com Physician Scraper?

- **Build physician datasets** - Collect consistent provider records for analytics, comparison tools, and internal directories.
- **Target specific markets** - Narrow results by specialty, state, city, or another supported location format.
- **Track public provider signals** - Compare ratings, review counts, specialties, experience, and new-patient availability across locations.
- **Reduce manual research** - Replace repetitive directory searches with repeatable Apify runs and scheduled collection.
- **Connect results to workflows** - Export the dataset to JSON, CSV, Excel, or XML, or send it to downstream tools through the Apify API, webhooks, and integrations.

### What data can you extract from Vitals.com?

Each saved item represents one unique physician or provider listing. Optional fields are included when Vitals.com publishes them.

| Field | Type | Description |
|-------|------|-------------|
| `providerid` | String | Unique provider identifier from the directory. |
| `intid` | String | Internal listing identifier when available. |
| `npi` | String | National Provider Identifier when available. |
| `name` | String | Full provider name. |
| `firstname` | String | Provider first name. |
| `middlename` | String | Provider middle name when available. |
| `lastname` | String | Provider last name. |
| `suffix` | String | Name suffix or credential label when available. |
| `gender` | String | Gender value published by the source when available. |
| `specialty` | String | Primary medical specialty. |
| `specialties` | String | Additional specialty labels associated with the listing. |
| `location` | String | Combined city and state value when available. |
| `city` | String | Practice city. |
| `state` | String | Practice state or region abbreviation. |
| `profileurl` | String | Direct Vitals.com provider profile URL. |
| `rating` | Number | Average rating score when available. |
| `schema_rating` | Number | Additional rating score published in the listing data. |
| `review_count` | Number | Number of patient reviews when available. |
| `number_of_ratings` | Number | Number of ratings when available. |
| `years_of_experience` | Number | Years of professional experience when available. |
| `total_awards` | Number | Number of awards associated with the provider. |
| `accepts_new_patients` | Boolean or String | New-patient availability value from the source. |
| `languages` | String | Languages spoken when listed. |
| `photourl` | String | Provider photo URL when available. |
| `degreeabbr` | String | Degree or qualification abbreviations. |
| `bio` | String | Plain-text provider biography when available. |
| `job_title` | String | Professional job title. |
| `display_type` | String | Provider display category from the listing. |
| `distance` | Number | Distance value when the source provides one. |
| `type` | String | Provider type. |
| `profiletype` | String | Profile category when available. |
| `source` | String | Record origin marker, normally `listing`. |

### How to scrape Vitals.com physician data

1. Open Vitals.com Physician Scraper on Apify.
2. Enter a specialty and optional location, or provide a direct Vitals.com directory URL.
3. Set the maximum number of results and pages to process.
4. Add Apify Proxy settings when collecting larger datasets or running recurring jobs.
5. Run the Actor and review the records in the Dataset.
6. Download the data or connect the Dataset to your application or automation workflow.

The Actor stops when it reaches `results_wanted`, exhausts the configured page limit, or has no more matching directory records. Records with the same provider identifier are saved only once during a run.

### Input Parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `startUrl` | String | No | - | Direct Vitals.com directory URL. When provided, it takes precedence over the generated specialty and location URL. |
| `specialty` | String | No | `Cardiovascular Disease` | Medical specialty or field, such as `Cardiology`, `Dermatology`, or `Psychiatry`. |
| `location` | String | No | `""` | City, state, or region used to narrow the directory search, such as `New York`, `California`, or `New York, NY`. |
| `insurance` | String | No | - | Reserved input shown in the Actor schema for insurance-related workflows. The current collection URL is built from `specialty` and `location`; apply insurance filtering to the returned dataset when needed. |
| `results_wanted` | Integer | No | `20` | Target number of unique physician records to save. Minimum value is `1`. |
| `max_pages` | Integer | No | `5` | Maximum number of directory pages to process. Minimum value is `1`. |
| `proxyConfiguration` | Object | No | `{"useApifyProxy": true}` | Apify Proxy settings for more reliable collection, especially for larger or recurring runs. |

### Usage Examples

#### Basic specialty search

Collect physician records for a specialty using the default result and page limits.

```json
{
  "specialty": "Cardiology",
  "results_wanted": 20
}
```

#### Specialty and location search

Collect dermatology providers in Florida and process up to three directory pages.

```json
{
  "specialty": "Dermatology",
  "location": "Florida",
  "results_wanted": 50,
  "max_pages": 3
}
```

#### Direct URL with proxy configuration

Start from a specific public Vitals.com directory URL and use an Apify residential proxy group for a larger run.

```json
{
  "startUrl": "https://www.vitals.com/cardiovascular-disease/ny",
  "results_wanted": 100,
  "max_pages": 5,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"]
  }
}
```

### Sample Output

The Dataset contains one JSON object per unique physician listing. Optional fields are omitted when the source does not provide them.

```json
{
  "providerid": "1AB150C9-9D65-4B93-BDCE-3536D6523B01",
  "intid": "123456",
  "npi": "1336372010",
  "name": "Mershed Kareem Alsamara",
  "firstname": "Mershed",
  "lastname": "Alsamara",
  "specialty": "Cardiovascular Disease",
  "specialties": "Cardiovascular Disease, Cardiologist",
  "location": "Richland, WA",
  "city": "Richland",
  "state": "WA",
  "profileurl": "https://www.vitals.com/doctors/mershed-kareem-alsamara",
  "rating": 5,
  "schema_rating": 4.97,
  "review_count": 706,
  "number_of_ratings": 706,
  "years_of_experience": 24,
  "total_awards": 2,
  "accepts_new_patients": true,
  "languages": "Arabic; English",
  "degreeabbr": "MD",
  "job_title": "Cardiologist",
  "type": "Physician",
  "source": "listing"
}
```

### Tips for best results

- Use a specific specialty such as `Cardiology`, `Neurology`, or `Pediatrics` for a more focused dataset.
- Add a state or city to reduce irrelevant records and make the results easier to analyze.
- Start with a smaller `results_wanted` value to confirm the output before running a broader collection.
- Use `startUrl` when you already have a Vitals.com directory page with the exact scope you need.
- Increase `max_pages` together with `results_wanted` when the target directory contains more matching providers.
- Use Apify Proxy for larger runs or schedules, and inspect the Dataset preview for optional-field coverage.
- Treat missing values as normal source variation. Not every provider publishes the same public information.

### Integrations and export formats

- **JSON** - Use the Dataset through the Apify API or application workflows.
- **CSV and Excel** - Analyze physician coverage, ratings, and locations in spreadsheet tools.
- **XML** - Support systems that require XML-based data exchange.
- **Google Sheets and Airtable** - Build searchable provider research tables.
- **Make and Zapier** - Trigger notifications, enrichment, or CRM actions after a run.
- **Webhooks** - Notify a downstream service when a run finishes.
- **Scheduling** - Refresh public directory data on a recurring schedule in Apify Console.

### Frequently Asked Questions

#### Can I search Vitals.com by specialty and location?

Yes. Provide `specialty`, `location`, or both. The Actor creates a directory search from those values and paginates until it reaches the requested result or page limit.

#### Can I provide my own Vitals.com URL?

Yes. Use `startUrl` with a public Vitals.com directory URL. It takes precedence over the specialty and location inputs.

#### Does the Actor collect full physician profile pages?

No. The current output is based on public physician directory listing data. It does not provide a separate full-profile enrichment option, so credentials or other fields appear only when they are present in the collected listing data.

#### How many records can one run return?

The run targets the number set in `results_wanted` and cannot exceed the records available within the configured page limit. For larger datasets, use separate specialty or location runs and combine the exported datasets.

#### Are duplicate physicians removed?

Yes. The Actor uses the provider identifier to avoid saving the same physician more than once during a run.

#### Why is a field missing from a record?

Vitals.com does not publish every field for every provider. The Actor keeps available values and omits empty values, so missing optional data usually reflects the source listing.

#### Can I collect insurance-filtered results?

The `insurance` field is present in the input schema, but the current URL generation uses specialty and location. For reliable insurance filtering, export the Dataset and filter the resulting records in your workflow.

#### Is it legal to collect Vitals.com data?

Public data collection may be subject to website terms, privacy rules, and other laws. You are responsible for confirming that your use complies with Vitals.com policies and applicable regulations, especially when handling healthcare-related information.

### Related Actors

For other physician and healthcare directory workflows from Shahid Irfan, see:

- [WebMD Doctor Scraper](https://apify.com/shahidirfan/webmd-doctor-scraper) - Collect doctor directory records, specialties, ratings, and locations from WebMD.
- [Practo Doctors Scraper](https://apify.com/shahidirfan/practo-doctors-scraper) - Collect doctor and clinic data from Practo, including specialties, fees, ratings, and practice details.
- [Oladoc Doctors Scraper](https://apify.com/shahidirfan/oladoc-scraper) - Collect doctor profiles, hospitals, consultation fees, availability, and services from Oladoc.
- [RateMDs Physician Scraper](https://apify.com/shahidirfan/ratemds-physician-scraper) - Collect physician specialties, ratings, review counts, locations, and public profile details from RateMDs.

### Support

For issues, feature requests, or public-source changes, use the Issues tab on the Actor page or contact the developer through Apify.

### Legal Notice

This Actor is intended for legitimate collection and analysis of publicly available physician directory information. Users are responsible for complying with Vitals.com terms, applicable privacy and healthcare data rules, and all other laws that apply to their use case.

# Actor input Schema

## `startUrl` (type: `string`):

Direct Vitals.com search URL. If set, overrides specialty/location/insurance parameters.

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

Medical specialty or field (e.g., Cardiology, Dermatology, Psychiatry).

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

State, city, or region to search (e.g., New York, California, Los Angeles).

## `insurance` (type: `string`):

Filter by accepted insurance (e.g., Aetna, Blue Cross, Cigna, Medicare).

## `results_wanted` (type: `integer`):

Target number of physician profiles.

## `max_pages` (type: `integer`):

Maximum number of search result pages to process.

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

Apify Proxy for enhanced reliability. Residential proxy recommended for best results.

## Actor input object example

```json
{
  "startUrl": "https://www.vitals.com/doctors?specialty=Cardiologist&location=New York",
  "specialty": "Cardiology",
  "location": "New York",
  "insurance": "Aetna",
  "results_wanted": 20,
  "max_pages": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

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

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "specialty": "Cardiovascular Disease",
    "location": "",
    "results_wanted": 20,
    "max_pages": 5
};

// Run the Actor and wait for it to finish
const run = await client.actor("shahidirfan/vitals-com-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": "Cardiovascular Disease",
    "location": "",
    "results_wanted": 20,
    "max_pages": 5,
}

# Run the Actor and wait for it to finish
run = client.actor("shahidirfan/vitals-com-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": "Cardiovascular Disease",
  "location": "",
  "results_wanted": 20,
  "max_pages": 5
}' |
apify call shahidirfan/vitals-com-scraper --silent --output-dataset

```

## MCP server setup

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