# NPI Registry Scraper - Healthcare Providers & Leads (`scrapesage/npi-nppes-scraper`) Actor

Scrape the NPPES NPI Registry: US doctors, clinicians & healthcare organizations by name, NPI, state, city, ZIP or specialty. Get addresses, phone & fax, taxonomies, licenses, org authorized officials, contact leads & lead scores. Monitor new registrations. No key.

- **URL**: https://apify.com/scrapesage/npi-nppes-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** Lead generation, Agents, Integrations
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.20 / 1,000 provider record scrapeds

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/platform/actors/running/actors-in-store#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

## NPI Registry Scraper — US Healthcare Providers, Organizations & Contact Leads

Pull clean, structured data from the **[NPPES NPI Registry](https://npiregistry.cms.hhs.gov/)** — the U.S. government's authoritative database of every healthcare provider with a **National Provider Identifier (NPI)**. Search **8M+ individual clinicians (NPI‑1)** and **healthcare organizations (NPI‑2)** by name, NPI number, **specialty**, **state**, **city** or **ZIP**, and get the full record: taxonomies, licenses, practice & mailing addresses, **phone & fax**, identifiers — plus ready‑to‑use **B2B contact leads** with a named decision‑maker and a 0–100 lead score.

No login, no API key, no browser. Fast, reliable extraction straight from the official CMS data source.

### Why this NPI / NPPES scraper?

Most NPI tools hand back the raw, deeply‑nested government JSON or a thin name‑and‑number list. This actor ships the **richest, cleanest dataset in the category** and turns the registry into a sales‑ready lead list — every record carries a phone number, and every organization carries its **authorized official** (a named owner/officer with title and a direct phone).

| Data | Generic NPI tools | This actor |
|---|---|---|
| NPI, type (individual/org), status | ✅ | ✅ |
| Clean name / organization name | partial | ✅ |
| **Primary specialty** + all taxonomies (code, license, state) | partial | ✅ |
| Practice **and** mailing address | partial | ✅ |
| **Phone & fax** (formatted) | ❌/partial | ✅ ~100% |
| **Organization authorized official** (name, title, direct phone) | ❌ | ✅ |
| Additional practice locations | ❌ | ✅ |
| Other identifiers (Medicaid / Medicare / etc.) | ❌ | ✅ |
| Contact‑lead record + **0–100 lead score** | ❌ | ✅ |
| Search by name / NPI / specialty / state / city / ZIP | partial | ✅ all |
| Cross‑combine many specialties × states in one run | ❌ | ✅ |
| **Only‑new monitoring** of fresh registrations | ❌ | ✅ |
| One clean table per entity (no empty columns) | ❌ | ✅ |

### Use cases

- **Healthcare B2B lead generation** — build targeted prospect lists for medical‑device, pharma, SaaS, billing, staffing, marketing and supply vendors. Filter by specialty + geography, then export name, organization, **phone**, address and the **authorized official** to your CRM.
- **Sales territory & market mapping** — count and locate every dentist, pharmacy, physical‑therapy clinic or nurse practitioner in a state, city or ZIP.
- **Provider data enrichment & validation** — look up NPIs in bulk to verify names, specialties, licenses and current addresses against the federal source of truth.
- **Recruiting & credentialing** — find clinicians by specialty and location, with license numbers and states.
- **Compliance & research** — reconcile provider rosters, dedupe directories, and track new enrollments over time.

### How to use

1. [Sign up for Apify](https://console.apify.com/sign-up) — the free plan is enough to try this actor.
2. Open the **NPI Registry Scraper**, choose a **specialty** (e.g. `Dentist`) and a **state** (e.g. `CA`), and pick what to output (**Providers** by default, or **Leads**).
3. Click **Start** and watch results stream into the dataset table.
4. **Export** as JSON, CSV, Excel, XML or RSS — or pull results programmatically via the [Apify API](https://docs.apify.com/api/v2).

### Input

```json
{
    "mode": "search",
    "outputType": "leads",
    "taxonomyDescription": "Dentist",
    "states": ["CA", "TX", "NY"],
    "enumerationType": "NPI-2",
    "maxResults": 500
}
```

- **mode** *(default `search`)* — `search` queries by criteria; `npiLookup` fetches specific NPI numbers from `npiNumbers`.
- **outputType** *(default `providers`)* — `providers` (full registry records), `leads` (contact‑focused + lead score), or `both`.
- **taxonomyDescription / specialty** — provider type from the NUCC taxonomy: `Dentist`, `Pharmacy`, `Physical Therapist`, `Internal Medicine`, `Nurse Practitioner`… (partial match + trailing `*` wildcard).
- **state / city / postalCode** — single values, or use **states / cities / postalCodes** arrays to cross‑combine many in one run.
- **firstName / lastName** *(individuals)* and **organizationName** *(organizations)* — supports a trailing `*` wildcard.
- **enumerationType** — limit to `NPI-1` (individuals) or `NPI-2` (organizations); blank = both.
- **npiNumbers** — one or more 10‑digit NPIs for `npiLookup` mode.
- **searchUrls** — paste NPPES API/registry URLs; their parameters are parsed into searches.
- **enrichContacts** *(default false)* — if a provider lists a website endpoint, fetch its homepage for emails/socials.
- **monitorMode / monitorKey** — emit only providers not seen in previous runs (ideal on a schedule).
- **maxResults**, **maxConcurrency**, **proxyConfiguration** — standard controls.

### Output

Set `outputType` to get one clean, dense table. A **provider** record (`type: "provider"`):

```json
{
    "type": "provider",
    "npi": "1063386555",
    "npiUrl": "https://npiregistry.cms.hhs.gov/provider-view/1063386555",
    "enumerationType": "NPI-2",
    "providerType": "Organization",
    "status": "Active",
    "organizationName": "1 Davison Ave Dentistry PLLC",
    "authorizedOfficialName": "Gavriel Gulamov",
    "authorizedOfficialTitle": "OWNER",
    "authorizedOfficialPhone": "(646) 593-9305",
    "primarySpecialty": "Dentist, General Practice",
    "primaryTaxonomyCode": "1223G0001X",
    "licenseNumber": "071234",
    "licenseState": "NY",
    "taxonomies": [{ "code": "1223G0001X", "description": "Dentist, General Practice", "primary": true, "state": "NY", "license": "071234" }],
    "practiceAddress": { "line1": "1 Davison Ave", "city": "Staten Island", "state": "NY", "postalCode": "10314-1234", "phone": "(646) 593-9305", "fax": null },
    "phone": "(646) 593-9305",
    "city": "Staten Island",
    "state": "NY",
    "enumerationDate": "2018-05-01T00:00:00.000Z",
    "scrapedAt": "2026-06-18T00:36:28.000Z"
}
```

A **lead** record (`type: "providerLead"`) distils the same provider into a contact row: `name`, `organizationName`, `primarySpecialty`, a named `contactName` / `contactTitle` / `contactPhone` (the org's authorized official, or the individual provider), `phone`, `fax`, `email` & `website` (when available), `address`, `city`, `state`, `licenseNumber` and a **`leadScore`** (0–100).

#### What to expect (field coverage)

NPPES is provider‑submitted federal data. Verified across specialties and states, you can typically expect:

| Field | Coverage |
|---|---|
| NPI, type, status, name/organization | ✅ ~100% |
| Primary specialty + taxonomies | ✅ ~100% |
| Practice address, city, state, ZIP | ✅ ~100% |
| **Phone** | ✅ ~100% · **fax** ~60–80% |
| Organization **authorized official** (name, title, phone) | ✅ for organizations (NPI‑2) |
| License number / state | ✅ when the taxonomy is state‑licensed |
| `email` / `website` | present only when the provider registered an endpoint (NPPES rarely lists a marketing site) — phone is always the primary contact |

A blank field means the provider didn't submit it — nothing is dropped, so you always get the richest record available.

### Automate & schedule

Run this actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** — start runs, fetch datasets, manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[Python](https://docs.apify.com/api/client/python/)** — official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** — run it daily/weekly with **monitor mode** to capture newly‑registered providers as fresh leads.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** — trigger downstream actions (CRM import, Slack alert, email sequence) the moment a run finishes.

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

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

const run = await client.actor('scrapesage/npi-nppes-scraper').call({
    mode: 'search',
    outputType: 'leads',
    taxonomyDescription: 'Pharmacy',
    state: 'TX',
    enumerationType: 'NPI-2',
    maxResults: 500,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} provider leads`);
```

### Integrate with any app

Connect the dataset to 5,000+ apps — no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** — multi‑step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** — push new provider leads straight into your CRM.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** — get notified when a monitored search finds new registrations.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** — auto‑export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** — pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** — trigger runs from commits or releases.

### Use with AI assistants (MCP)

The output is clean, LLM‑ready JSON. Call this actor from Claude, ChatGPT or any agent framework through the **[Apify MCP server](https://docs.apify.com/platform/integrations/mcp)** — ask your assistant to "list every pharmacy in Texas with a phone number and the owner's name" and let it run the scraper for you.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### More scrapers from scrapesage

Build a complete **healthcare data & B2B lead‑gen stack**:

- **[CMS Open Payments Scraper](https://apify.com/scrapesage/open-payments-scraper)** — drug & device industry payments to physicians and teaching hospitals.
- **[Clinical Trials Scraper](https://apify.com/scrapesage/clinical-trials-scraper)** — ClinicalTrials.gov studies, sponsors and research‑site/investigator leads.
- **[FDA openFDA Scraper](https://apify.com/scrapesage/fda-scraper)** — drug/device/food recalls, adverse events, clearances and manufacturer leads.
- **[Healthgrades Scraper](https://apify.com/scrapesage/healthgrades-scraper)** — physician profiles, ratings, reviews and contact details.
- **[WebMD Scraper](https://apify.com/scrapesage/webmd-scraper)** — provider directory profiles, specialties and reviews.
- **[TherapyDen Scraper](https://apify.com/scrapesage/therapyden-scraper)** — therapist & mental‑health provider leads.
- **[Caring Senior Living Scraper](https://apify.com/scrapesage/caring-senior-living-scraper)** — senior‑living & care facility leads.
- **[Website Contact Scraper](https://apify.com/scrapesage/website-contact-scraper)** — enrich any domain list with emails, phones and socials.

### Tips

- **Pick one `outputType`** (Providers or Leads) for a clean, fully‑populated table that's perfect for direct export. Use `both` to keep the full record alongside the lead row.
- **Going deep in one area?** Each NPPES query returns up to 1,200 results — narrow by specialty + state + city (or ZIP) to slice a large market into complete, exportable chunks.
- **Targeting organizations?** Set `enumerationType` to `NPI-2` — every org carries its **authorized official** (a named owner/officer with a direct phone), the highest‑value B2B contact in the registry.
- **Recurring fresh leads:** combine [Schedules](https://docs.apify.com/platform/schedules) with **monitor mode** (and a unique `monitorKey` per search) to receive only newly‑registered providers each run.

### FAQ

**Where does the data come from?** The official **NPPES NPI Registry API** (`npiregistry.cms.hhs.gov`), published by the U.S. Centers for Medicare & Medicaid Services (CMS). It's public data — no key or login required.

**What's an NPI?** A National Provider Identifier — a unique 10‑digit number every U.S. healthcare provider and organization must have for HIPAA transactions. NPI‑1 = individuals; NPI‑2 = organizations.

**Can I look up specific providers?** Yes — set `mode` to `npiLookup` and paste 10‑digit NPI numbers into `npiNumbers`.

**How do I get the owner / decision‑maker?** For organizations (NPI‑2), the **authorized official** (name, title and direct phone) is included automatically and used as the lead's contact.

**Do I get emails?** NPPES rarely stores a marketing website or email, so the primary contact is the registered **phone** (always present) and, for organizations, the authorized official. If a provider registered a website endpoint, enable `enrichContacts` to scrape it for emails and social links.

**Can I export to Google Sheets, CSV or Excel?** Yes — one click in the dataset view, or automatically on every run via the [Google Drive integration](https://docs.apify.com/platform/integrations/drive).

**Is this legal?** This actor collects publicly available U.S. government data. You're responsible for using it in compliance with applicable laws (e.g. TCPA/CAN‑SPAM for outreach) and Apify's terms.

### Need help?

Open an issue on the actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome — this actor is actively maintained.

# Actor input Schema

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

How to find providers. "search" queries the registry by criteria (name, location, specialty…). "npiLookup" fetches specific NPI numbers directly.

## `outputType` (type: `string`):

"providers" = full registry records (taxonomies, licenses, addresses, identifiers). "leads" = contact-focused B2B leads (named contact, phone, specialty, lead score). "both" emits one of each per provider.

## `taxonomyDescription` (type: `string`):

Provider type / specialty from the NUCC taxonomy, e.g. "Dentist", "Physical Therapist", "Pharmacy", "Internal Medicine", "Nurse Practitioner". Partial matches and a trailing \* wildcard are supported.

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

Friendly alias for the specialty / taxonomy field above — use either one.

## `taxonomyDescriptions` (type: `array`):

Run several specialties in one go (combined with each state/city/ZIP below).

## `state` (type: `string`):

Two-letter US state/territory code, e.g. CA, TX, NY, FL.

## `states` (type: `array`):

Run several states in one go (cross-combined with each specialty/city/ZIP).

## `city` (type: `string`):

City name to match against the provider address.

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

Run several cities in one go (cross-combined with each specialty/state/ZIP).

## `postalCode` (type: `string`):

5-digit ZIP. A trailing \* wildcard is supported (e.g. 902\* for the 902xx area).

## `postalCodes` (type: `array`):

Run several ZIP codes in one go (cross-combined with the other criteria).

## `firstName` (type: `string`):

For NPI-1 individual providers. Trailing \* wildcard supported.

## `lastName` (type: `string`):

For NPI-1 individual providers. Trailing \* wildcard supported.

## `organizationName` (type: `string`):

For NPI-2 organizations, e.g. "CVS Pharmacy", "Mayo Clinic". Trailing \* wildcard supported.

## `enumerationType` (type: `string`):

Limit to individuals (NPI-1) or organizations (NPI-2). Leave blank for both.

## `addressPurpose` (type: `string`):

Match the state/city/ZIP against the provider's LOCATION (practice) or MAILING address. Leave blank for the default.

## `countryCode` (type: `string`):

Two-letter country code; defaults to US.

## `npiNumbers` (type: `array`):

One or more 10-digit NPI numbers to fetch directly.

## `searchUrls` (type: `array`):

Paste NPPES API or registry URLs — their query parameters (state, taxonomy, name, number…) are parsed and added as searches.

## `enrichContacts` (type: `boolean`):

When building leads, if a provider lists a website endpoint, fetch its homepage to pull emails and social links. Off by default (NPPES rarely lists a marketing website; phone, fax and the org authorized official are always included regardless).

## `maxResults` (type: `integer`):

Maximum number of providers to scrape. Each NPPES query returns up to 1,200 results; narrow by specialty/state/city to go deeper.

## `deduplicateResults` (type: `boolean`):

Skip duplicate providers (same NPI) within a run.

## `monitorMode` (type: `boolean`):

Remember NPIs seen in previous runs (in a named key-value store) and emit only newly-appearing providers — ideal on a schedule to capture new healthcare registrations as fresh leads.

## `monitorKey` (type: `string`):

Name your monitor so different searches keep separate memory (e.g. "ca-dentists").

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

Number of parallel requests (NPI lookups and contact enrichment).

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

The NPPES API is clean from Apify datacenter proxies; a fresh IP is rotated per request to spread the per-IP rate limit.

## `urlsFromFile` (type: `string`):

Paste a list of URLs (one per line), OR one link to a .txt/.csv file, Google Sheet or Google Drive file containing them. Lets you import many Start URLs at once instead of typing each. Google Sheet/Drive share links are handled automatically.

## Actor input object example

```json
{
  "mode": "search",
  "outputType": "providers",
  "taxonomyDescription": "Dentist",
  "state": "CA",
  "enumerationType": "",
  "addressPurpose": "",
  "countryCode": "US",
  "npiNumbers": [],
  "enrichContacts": false,
  "maxResults": 200,
  "deduplicateResults": true,
  "monitorMode": false,
  "monitorKey": "default",
  "maxConcurrency": 6,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

All scraped provider and lead records as JSON items in the default dataset.

# 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 = {
    "taxonomyDescription": "Dentist",
    "state": "CA",
    "npiNumbers": [],
    "urlsFromFile": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/npi-nppes-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 = {
    "taxonomyDescription": "Dentist",
    "state": "CA",
    "npiNumbers": [],
    "urlsFromFile": "",
}

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/npi-nppes-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 '{
  "taxonomyDescription": "Dentist",
  "state": "CA",
  "npiNumbers": [],
  "urlsFromFile": ""
}' |
apify call scrapesage/npi-nppes-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapesage/npi-nppes-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/LTWY4E5mUwH6fPvtC/builds/lIwOuqtAj1hk3xl56/openapi.json
