# NPI Registry Scraper | 7M+ US Healthcare Providers (CMS) (`haketa/nppes-npi-registry-scraper`) Actor

NPPES NPI Registry scraper & API: search 8M+ US healthcare providers and export NPI, name, taxonomy and specialty, practice and mailing address, phone, credentials and enumeration date. Healthcare provider data, verification and lead generation — fast, no login.

- **URL**: https://apify.com/haketa/nppes-npi-registry-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Developer tools, Automation, Lead generation
- **Features:** Limited permissions
- **Stats:** 25 total users, 5 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

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

## NPI Registry Scraper — 7M+ US Healthcare Providers from the Official CMS NPPES API

> **The most complete NPPES NPI Registry data extraction actor on Apify.** This **NPPES scraper** pulls every licensed US healthcare provider — physicians, NPs, PAs, RNs, pharmacists, dentists, therapists, hospitals, clinics, group practices, pharmacies — straight from the **official Centers for Medicare & Medicaid Services (CMS) National Plan and Provider Enumeration System** at [npiregistry.cms.hhs.gov](https://npiregistry.cms.hhs.gov/). **Scrape the NPI Registry** by NPI, name, specialty (taxonomy), city, state, or ZIP — **no login, no coding, no scraping of private sites — 100% official public CMS data.**

Export to **JSON, CSV, Excel, or API**. ~**7,000,000+ providers** indexed, no auth, no hard rate limit.

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue?style=for-the-badge)](https://apify.com/haketa/nppes-npi-registry-scraper)
[![Live Data](https://img.shields.io/badge/Data-Live_NPPES_Registry-orange?style=for-the-badge)]()
[![Coverage](https://img.shields.io/badge/Records-7M%2B_US_Providers-purple?style=for-the-badge)]()
[![Scale](https://img.shields.io/badge/Pagination-1%2C000%2B_Auto--Sharded-green?style=for-the-badge)]()
[![Export](https://img.shields.io/badge/Export-JSON_%7C_CSV_%7C_Excel_%7C_API-007AFF?style=for-the-badge)]()

> Built for **pharma & med-device sales teams, healthcare recruiters & locum/travel-nursing staffing, payers & provider-directory teams, credentialing/compliance (CVO) analysts, healthcare M\&A diligence, telehealth launch teams, B2B healthcare SaaS marketers, public-health researchers, and investigative journalists** who need clean, current, structured US provider data.

> ✅ **Freshly verified:** a benchmark run pulled **500+ unique nurse-practitioner records in ~24 seconds** with **100% coverage of every core identity field** (NPI, name, specialty/taxonomy, license + state, city/state/ZIP, phone, status, enumeration date) and **zero duplicates**. A companion organization run returned a **named Authorized Official decision-maker for 100% of NPI-2 records**.

***

### ⚡ At a glance

| Feature | Details |
| :--- | :--- |
| **🩺 Data Coverage** | 7,000,000+ active & historical US healthcare providers — both **NPI-1 (Individuals)** and **NPI-2 (Organizations)** |
| **🔍 Search Modes** | By Specialty / Taxonomy (dropdown or custom text), Provider Name, Organization Name, City / State / ZIP, or direct 10-digit NPI lookup |
| **📇 B2B Contact Fields** | Practice & mailing phones/faxes, full street addresses, state license numbers, plus named `authorizedOfficial` (name, title, direct phone) on organizations |
| **🔢 1,000+ Deep Pagination** | Automatic skip-offset pagination (`200` records/page) + **automatic state & alphabetical A–Z sharding** to bypass the 1,200-record single-query ceiling |
| **🛡️ Deduplication** | 100% deduplicated by 10-digit `npi` across multi-state, multi-city, and prefix-sharded queries |
| **📤 Export Formats** | Bulk export to JSON, CSV, Excel (XLSX), XML, HTML, RSS, or live Apify API |

***

### 🔎 Why scrape the NPPES NPI Registry?

Every clinician, allied-health professional, and healthcare organization operating in the United States is required by HIPAA to obtain a **National Provider Identifier (NPI)** before submitting electronic healthcare transactions. The result is a freely-queryable federal registry of **7,000,000+ providers** — the single richest, most authoritative source of US healthcare-provider information in existence. It is refreshed continuously as new providers enumerate and existing providers update their licensure, address, phone, or specialty.

That data is enormously valuable: it is the backbone of pharma sales targeting, healthcare recruiting, payer network management, credentialing, M\&A diligence, and health-policy research. But collecting it by hand — or by rolling your own API client — is painful. The CMS API caps every response at **200 records**, hands back **HTTP 200 with an error object** instead of a clean error status, returns **deeply nested JSON** that shape-shifts between individual (NPI-1) and organization (NPI-2) records, and offers **no bulk-download endpoint and no `next_page` token**. A single typo in a state code silently returns zero results.

This **NPPES scraper** turns that raw API into a structured, paginated, deduplicated, ready-for-CRM/data-warehouse dataset. You pick filters; it builds the full query matrix, paginates every page, retries failures, deduplicates by NPI, flattens the nested JSON into one clean row per provider, and streams the result to your Apify dataset.

**Common reasons people scrape the NPPES NPI Registry:**

- **Build prescriber / provider target lists** by specialty + geography for pharma and med-device sales.
- **Source and verify clinicians** (physicians, NPs, PAs, RNs, CRNAs, PTs, pharmacists) for staffing, locum tenens, and travel nursing.
- **Audit and refresh payer provider directories** for Network Adequacy / No Surprises Act compliance.
- **Verify NPIs at claim submission** and automate credentialing to replace per-lookup verification APIs.
- **Run healthcare M\&A diligence** on a target practice's provider roster and multi-state license footprint.
- **Scout state-by-state licensed providers** for telehealth and digital-health launches.
- **Research the US healthcare workforce** — provider density, pharmacy deserts, primary-care shortage areas.

***

### ✨ What this NPPES NPI Registry scraper does

This actor queries the **official US federal National Provider Identifier (NPI) registry** — the authoritative source-of-truth for every provider authorized to bill Medicare, Medicaid, or any HIPAA-covered payer.

- ✅ **Five search modes** — by **specialty/taxonomy** (dropdown or custom text), by **name** (first/last), by **organization name**, by **city / state / ZIP**, and by **direct NPI lookup** (paste 10-digit NPIs for the fastest, most precise mode).
- ✅ **Unlocked 1,000+ deep pagination & auto-sharding** — each registry page returns up to **200 records**; when your `maxRecords` target exceeds a single query's 1,200-record ceiling (`skip=1000`), the actor automatically shards across US states and alphabetical prefixes (`A*`–`Z*`) to deliver **thousands to tens of thousands** of unique providers in a single run.
- ✅ **NPI-1 (individual) + NPI-2 (organization)** support in one flat schema — physicians, NPs, PAs, RNs, dentists, pharmacists, therapists *and* hospitals, clinics, group practices, pharmacies, FQHCs, SNFs, labs, DME suppliers.
- ✅ **Rich captured fields**, grouped:
  - **Identity & status:** `npi`, `enumerationType`, `firstName`, `middleName`, `lastName`, `fullName`, `credential`, `organizationName`, `organizationalSubpart`, `gender`, `status` (Active/Deactivated), `soleProprietor`.
  - **Decision-maker contact (organizations):** `authorizedOfficial` — the named human required on every NPI-2 org (`firstName`, `lastName`, `fullName`, `title`, `phone`, `credential`).
  - **Specialty & licensure:** `primaryTaxonomyCode`, `primaryTaxonomyDesc`, `primaryLicense`, `primaryLicenseState`, plus the full `taxonomies[]` array.
  - **Addresses & contact:** `mailingAddress`, `locationAddress`, top-level `phone`, `mailingPhone`, `city`, `state`, `postalCode`, `country`, and `practiceLocations[]`.
  - **Dates & provenance:** `enumerationDate`, `certificationDate`, `lastUpdated`, `scrapedAt`, `searchQuery`, `sourceUrl`.
  - **Extras:** `identifiers[]` (state Medicaid IDs, license IDs), `otherNames[]` (DBAs, former names, AKAs), `endpoints[]` (FHIR Direct messaging).
- ✅ **Multi-filter fan-out** — supply multiple cities × states and the actor builds a Cartesian task list, running each combination as a discrete query.
- ✅ **NPI-level deduplication** — a `Set` of seen NPIs guarantees no provider is saved twice across overlapping queries.
- ✅ **3-attempt retry** with exponential backoff + jitter; **polite pacing** via a configurable `requestDelay`.
- ✅ **Clean exit on empty results** — a zero-match or modifier-only query exits cleanly with a descriptive status message instead of crashing, so it never dents a scheduled pipeline's success rate.
- ✅ **Lightweight & fast** — no browser overhead, very low compute cost, and high throughput.
- ✅ **Export** to JSON, CSV, Excel (XLSX), HTML, XML, RSS, or JSON Lines — from the UI or the dataset API.

***

### 🎯 Use cases

- **Pharma & medical-device sales targeting** — build prescriber lists by specialty + geography, find newly-enumerated specialists early, map territories by provider density.
- **Healthcare staffing, locum tenens & travel nursing** — source and verify physicians, NPs, PAs, RNs, CRNAs, PTs by specialty + state + active status; find multi-state-licensed clinicians via the `taxonomies[]` license array.
- **Insurance & payer networks** — audit network adequacy per specialty per ZIP, refresh provider directories monthly, reconcile billing vs. rendering NPIs.
- **Compliance, credentialing & claims verification** — verify NPIs at claim submission, start OIG LEIE / SAM.gov exclusion checks from a verified roster, monitor `status: Deactivated` changes.
- **Healthcare M\&A & investor diligence** — inventory a target's provider roster, quantify multi-state license footprint, assess specialty mix at acquisition.
- **Telehealth & digital-health launch** — find physicians licensed in every launch state, recruit clinicians by specialty + geography, run clinician KYC at onboarding.
- **B2B healthcare SaaS marketing & ABM** — segment by practice type, reach the named `authorizedOfficial` decision-maker directly, enrich inbound leads by NPI lookup.
- **Public health, policy & workforce research** — map provider supply per capita, identify pharmacy / primary-care / mental-health deserts, track workforce trends.

***

### 📥 Input

Supply at least one substantive criterion — a **specialty**, **name**, **organization name**, **city**, **ZIP**, or an **NPI**. A `states` / `enumerationType` / `addressPurpose` filter is a *modifier*: it narrows a substantive search but can't run on its own (the CMS API rejects it). Leave the **whole form empty** for a ready-made mixed sample across popular specialties (capped to ~100 records) so a first run is never zero.

| Parameter | Type | Description |
|---|---|---|
| `specialty` | `string` (select) | Provider specialty / taxonomy from a dropdown (e.g. Family Medicine, Cardiology, Nurse Practitioner, Pharmacy, Dentist, Hospital). Fastest way to pull a targeted list. |
| `specialtyCustom` | `string` | Any CMS taxonomy phrase not in the dropdown (partial match), e.g. `"Neurology"`, `"Oncology"`, `"Acupuncturist"`. Overrides the dropdown when set. |
| `states` | `array<string>` | 2-letter US state / territory codes (`NY`, `CA`, `TX`, `PR`…). Each state runs as a separate query. **Modifier** — pair with a substantive criterion. |
| `enumerationType` | `enum` | `NPI-1` = individuals (doctors, nurses…), `NPI-2` = organizations (hospitals, clinics, pharmacies), `any` = both. |
| `organizationName` | `string` | Organization legal-business-name search (e.g. `"Mount Sinai"`, `"Kaiser Permanente"`, `"Walgreens"`). |
| `firstName` | `string` | Individual first name (partial match). Best paired with a last name + state. |
| `lastName` | `string` | Individual last name (partial match). |
| `cities` | `array<string>` | City-name filter (e.g. `["New York","Brooklyn"]`). Each city runs as a separate query. |
| `postalCode` | `string` | ZIP filter, partial match (`"100"` matches all `100xx` ZIPs). |
| `npis` | `array<string>` | 10-digit NPI numbers for **direct lookup** — the fastest, most precise mode. Each NPI becomes its own task. |
| `addressPurpose` | `enum` | Match on `LOCATION` (practice), `MAILING`, `PRIMARY`, `SECONDARY`, or `any`. **Modifier.** |
| `maxRecords` | `integer` | Hard cap across all queries. `0` = unlimited (pages until every query exhausts). Default `100`. |
| `requestDelay` | `integer` | Milliseconds between page fetches (100–10000). 500–2000 ms is courteous. Default `800`. |
| `proxyConfiguration` | `object` | Optional Apify proxy. **Not required** — CMS NPPES is a public unrestricted API. |

#### Example input

```json
{
  "specialty": "Nurse Practitioner",
  "states": ["CA", "TX", "FL", "NY"],
  "enumerationType": "NPI-1",
  "maxRecords": 500,
  "requestDelay": 400,
  "proxyConfiguration": { "useApifyProxy": false }
}
```

Direct NPI lookup (fastest mode):

```json
{ "npis": ["1982445060", "1932487765", "1689675476"] }
```

Organization search:

```json
{
  "specialty": "Pharmacy",
  "organizationName": "Walgreens",
  "states": ["CA"],
  "enumerationType": "NPI-2",
  "maxRecords": 1000
}
```

<details>
<summary><strong>Deep 2,500+ nationwide specialty sweep with automatic state sharding (click to expand)</strong></summary>

```json
{
  "specialty": "Cardiology",
  "states": [],
  "enumerationType": "NPI-1",
  "maxRecords": 2500,
  "requestDelay": 400
}
```

</details>

<details>
<summary><strong>Hospital & clinic decision-maker (`authorizedOfficial`) B2B lead list (click to expand)</strong></summary>

```json
{
  "specialty": "Clinic/Center",
  "states": ["TX", "FL", "NY"],
  "enumerationType": "NPI-2",
  "maxRecords": 1500,
  "requestDelay": 500
}
```

</details>

***

### 📤 Output

Every record — individual or organization — uses the same flat JSON shape, so downstream consumers ingest the whole dataset without per-type branching. The example below is a **real record from the 2026-11-02 verification run** (phone shown as published by CMS):

```json
{
  "npi": "1750767083",
  "enumerationType": "NPI-1",
  "firstName": "DANIELLE",
  "lastName": "AAROE",
  "middleName": "JANNETTE",
  "fullName": "DANIELLE JANNETTE AAROE",
  "credential": "Family Nurse Practit",
  "organizationName": null,
  "organizationalSubpart": null,
  "authorizedOfficial": null,
  "gender": "F",
  "status": "Active",
  "soleProprietor": "NO",
  "enumerationDate": "2015-08-10",
  "certificationDate": null,
  "lastUpdated": "2015-08-10",
  "primaryTaxonomyCode": "363LF0000X",
  "primaryTaxonomyDesc": "Nurse Practitioner, Family",
  "primaryLicense": "95002487",
  "primaryLicenseState": "CA",
  "taxonomies": [
    { "code": "363LF0000X", "desc": "Nurse Practitioner, Family", "license": "95002487", "state": "CA", "primary": true, "taxonomyGroup": "" }
  ],
  "mailingAddress": {
    "address1": "2767 OLIVE HIGHWAY", "address2": "OROVILLE HOSPITAL",
    "city": "OROVILLE", "state": "CA", "postalCode": "959666185",
    "country": "United States", "phone": "530-533-8500", "fax": null, "purpose": "MAILING"
  },
  "locationAddress": {
    "address1": "2767 OLIVE HIGHWAY", "address2": "OROVILLE HOSPITAL",
    "city": "OROVILLE", "state": "CA", "postalCode": "959666185",
    "country": "United States", "phone": "530-533-8500", "fax": null, "purpose": "LOCATION"
  },
  "phone": "530-533-8500",
  "mailingPhone": "530-533-8500",
  "city": "OROVILLE",
  "state": "CA",
  "postalCode": "959666185",
  "country": "United States",
  "practiceLocations": null,
  "identifiers": null,
  "otherNames": null,
  "endpoints": null,
  "searchQuery": "taxonomy_description=Nurse Practitioner&state=CA&enumeration_type=NPI-1",
  "sourceUrl": "https://npiregistry.cms.hhs.gov/provider-view/1750767083",
  "scrapedAt": "2026-11-02T00:00:00.000Z"
}
```

And a **real organization (NPI-2) record** from the companion verification run, showing the named `authorizedOfficial` decision-maker:

```json
{
  "npi": "1649791633",
  "enumerationType": "NPI-2",
  "firstName": null,
  "lastName": null,
  "fullName": "10TH AVENUE PHARMACY",
  "credential": null,
  "organizationName": "10TH AVENUE PHARMACY",
  "organizationalSubpart": "NO",
  "authorizedOfficial": {
    "firstName": "EMMANUEL",
    "lastName": "ACHOLONU",
    "fullName": "Dr. EMMANUEL ACHOLONU",
    "title": "Director",
    "phone": "3232987693",
    "credential": null
  },
  "gender": null,
  "status": "Active",
  "soleProprietor": null,
  "enumerationDate": "2017-06-29",
  "primaryTaxonomyDesc": "Pharmacy",
  "phone": "323-298-7693",
  "city": "LOS ANGELES",
  "state": "CA",
  "sourceUrl": "https://npiregistry.cms.hhs.gov/provider-view/1649791633"
}
```

#### Field reference

| Field | Coverage | Description |
| :--- | :--- | :--- |
| 🆔 `npi` | 🟢 High (100%) | 10-digit National Provider Identifier (federal primary key). |
| 🏷️ `enumerationType` | 🟢 High (100%) | `NPI-1` (individual) or `NPI-2` (organization). |
| 👤 `fullName` | 🟢 High (100%) | Joined individual name, or organization legal name. |
| 📛 `firstName` / `middleName` / `lastName` | 🟢 High (NPI-1) | Individual name parts (null for orgs). First/last 100% on NPI-1; middle name ~50%. |
| 🎓 `credential` | 🟡 Conditional (~79% NPI-1) | Professional suffix (`MD`, `DO`, `NP`, `PA`, `RN`, `DDS`, `PharmD`, `LCSW`, `PT`…). |
| 🏥 `organizationName` | 🟢 High (100% NPI-2) | Legal business name (NPI-2). Null for individuals. |
| 🏢 `organizationalSubpart` | 🟢 High (NPI-2) | `YES`/`NO` — whether an NPI-2 org is a sub-part of a parent org. |
| 👔 `authorizedOfficial` | 🟢 High (~100% NPI-2) | **Named org decision-maker** (`firstName`, `lastName`, `fullName`, `title`, `phone`, `credential`). |
| ⚧️ `gender` / `soleProprietor` | 🟢 High (NPI-1) | `M`/`F` gender and `YES`/`NO` sole-proprietor status (individuals only). |
| ✅ `status` | 🟢 High (100%) | `Active` or `Deactivated`. |
| 📅 `enumerationDate` / `lastUpdated` | 🟢 High (100%) | NPI first-assigned date and most-recent update (`YYYY-MM-DD`). |
| 🗓️ `certificationDate` | 🟡 Conditional | Most-recent certification date when published. |
| 🩺 `primaryTaxonomyCode` / `primaryTaxonomyDesc` | 🟢 High (100%) | NUCC taxonomy code + human-readable specialty. |
| 📜 `primaryLicense` / `primaryLicenseState` | 🟢 High (~98%) | State license number + 2-letter state for the primary taxonomy. |
| 🗂️ `taxonomies` | 🟢 High (100%) | Full array of taxonomies (code, desc, license, state, primary flag, group). |
| 📍 `mailingAddress` / `locationAddress` | 🟢 High (100%) | Full nested addresses (`address1`, `address2`, `city`, `state`, `postalCode`, `country`, `phone`, `fax`, `purpose`). |
| 📞 `phone` / `mailingPhone` | 🟢 High (~99%) | Location (practice) phone and mailing phone. |
| 🏙️ `city` / `state` / `postalCode` / `country` | 🟢 High (100%) | Top-level location (LOCATION → MAILING fallback). |
| 🗺️ `practiceLocations` | 🟡 Conditional | Multi-site organizations' secondary physical practice locations. |
| 🔢 `identifiers` / `otherNames` / `endpoints` | 🟡 Conditional | State Medicaid IDs, former names/DBAs, and FHIR Direct endpoints when published. |
| 🔗 `searchQuery` / `sourceUrl` / `scrapedAt` | 🟢 High (100%) | Exact filter provenance, canonical provider-view URL, and ISO-8601 scrape timestamp. |

> **Honest note on coverage:** core identity/specialty/location fields populate at ~100%. Fields that are **genuinely optional or type-specific** behave as expected: `authorizedOfficial`/`organizationName`/`organizationalSubpart` populate for **organizations** (null for individuals); `gender`/`soleProprietor`/`credential` populate for **individuals** (null for orgs); and `identifiers`/`otherNames`/`endpoints`/`practiceLocations` populate **only when the provider published them** to CMS. None of these are bugs — they reflect exactly what the registry contains for each record.

***

### 🔁 Pagination & scale

The CMS NPPES API returns at most **200 records per call** and offers no `next_page` token. This actor paginates with the **`skip` offset**: it fetches `skip=0`, then `skip=200`, `skip=400`, … advancing until a query returns fewer than 200 rows (the last page) or the global `maxRecords` cap is reached. When you supply multiple states / cities, each combination runs as its own paginated task, and results are **deduplicated by NPI** across all tasks.

- **Scale:** a single run can return tens, thousands, or tens of thousands of de-duplicated provider records. Set `maxRecords: 0` for unlimited; set a cap for fast, predictable sampling.
- **Verified:** the 2026-11-02 benchmark pulled **500 unique records in ~24 seconds** with 0 duplicates, deep-paginating a broad California query. Pagination has been verified past `skip=10000` on very broad queries.
- **Tip for huge pulls:** for "every provider in a big state", split into multiple narrower queries (by city or ZIP) so each task's pagination stays manageable and fast.

***

### ⚙️ How to use

1. **On Apify Console:** open the actor, pick a **Specialty** (and optionally **States**, **Provider Type**), or type a **Name / Organization / NPI**, set **Max Records**, and click **Start**.
2. **Via API:** `POST https://api.apify.com/v2/acts/haketa~nppes-npi-registry-scraper/runs?token=YOUR_TOKEN` with a JSON body of the input above.
3. **On a schedule:** use Apify's built-in Scheduler (any cron) to refresh your NPI dataset daily/weekly.
4. **Choose your export:** JSON, CSV, Excel (XLSX), HTML, XML, RSS, or JSON Lines — from the dataset UI or the dataset API.
5. **Integrate:** push results to **Make, Zapier, n8n, Google Sheets, a webhook, or your data warehouse** (Postgres / Snowflake / BigQuery) keyed on `npi`.

#### API run (Python)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("haketa/nppes-npi-registry-scraper").call(run_input={
    "specialty": "Cardiology",
    "states": ["NY", "NJ", "CT"],
    "enumerationType": "NPI-1",
    "maxRecords": 2000
})
for p in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(p["npi"], p["fullName"], p["credential"], p["primaryTaxonomyDesc"], p["city"], p["state"], p["phone"])
```

***

### 💡 Tips

- **Search by specialty text, not codes** — `specialty: "Cardiology"` or `specialtyCustom: "Oncology"` works on the human-readable NUCC taxonomy; you never need the 10-character codes.
- **Use the `npis` array for verification** — nightly compliance checks of an employed-provider roster run fastest in direct-lookup mode (one request per NPI).
- **Target the named decision-maker** — for B2B outreach to hospitals/clinics/pharmacies, use `enumerationType: "NPI-2"` and read the `authorizedOfficial` object (name, title, direct phone).
- **Multi-state licensure signal** — pull NPI-1 records and inspect the `taxonomies[]` array for licenses in multiple states, the gold signal for telehealth-ready / travel-ready clinicians.
- **Split huge geographies** — for an entire large state, break the pull into cities or ZIPs to keep each task fast; the actor deduplicates by NPI across all of them.
- **Mind the cap order** — `maxRecords` is a global cap iterated task-by-task, so a broad first query (e.g. a populous state) can fill the cap before later tasks run. Raise `maxRecords` or narrow the first query to spread results across states.
- **Watch spellings** — use 2-letter uppercase state codes (`NY`, not `Ny`) and the current specialty label (`"Family Medicine"`, not the deprecated `"Family Practice"`).

***

### ❓ FAQ

#### How many records can I get, and how fast?

Each registry page returns 200 records, and single queries cap at 1,200 records (`skip=1000`). When you request `maxRecords > 1000` (or `0` for unlimited), the actor **automatically shards** across US states and alphabetical name prefixes (`A*`–`Z*`), allowing a single run to harvest **1,000 to 50,000+ unique providers** seamlessly. A 500-record run finishes in ~24 seconds; multi-thousand-record statewide sweeps finish in 1–3 minutes.

#### Do I need proxies or a login?

**No.** The NPPES registry is an open public federal system — no login or API key is required. An optional `proxyConfiguration` field is available if needed, and defaults to off.

#### How fresh is the data?

**Live at run time.** Every page is fetched directly from the federal registry at the moment of the run, reflecting new enumerations, address changes, and license updates immediately.

#### Can I filter by specialty, state, city, or ZIP?

Yes — by `specialty`/`specialtyCustom`, `states`, `cities`, and `postalCode`. A state / provider-type / address-purpose filter is a **modifier** that must be paired with a substantive criterion (specialty, name, organization, city, ZIP, or NPI).

#### Do I get phone numbers and a named contact?

**Yes.** Every address carries a phone (`phone` for practice location, `mailingPhone` for mailing). For **organizations (NPI-2)** you also get the **Authorized Official** — a named CEO / Administrator / Director / Pharmacist-in-Charge with a direct phone — populated for ~100% of NPI-2 records in our sampling.

#### Do I get email addresses?

**No.** CMS does not collect or publish provider email addresses. The `endpoints[]` field exposes FHIR Direct secure-messaging endpoints when present (not general-purpose email).

#### Does it cover all 50 states and territories?

Yes — all 50 states + DC, plus Puerto Rico (`PR`), US Virgin Islands (`VI`), Guam (`GU`), American Samoa (`AS`), and Northern Mariana Islands (`MP`). It covers **US providers only**.

#### What happens if my query returns zero results?

The actor **exits cleanly** with a descriptive status message (it does not fail the run). Common causes: a misspelled state code, a deprecated specialty label, or a modifier-only filter with no companion criterion.

#### Can I export to CSV / Excel / JSON, and schedule it?

Yes to both. Export from the dataset view (or API) to JSON, CSV, Excel, HTML, XML, RSS, or JSON Lines, and schedule the actor on any cron with Apify's Scheduler + Google Sheets / webhook / warehouse integrations.

***

### 🔗 Related scrapers

Compose these with the NPI Registry Scraper to cross-reference license numbers, enrich leads, and build full healthcare/compliance pipelines:

- [WhatClinic.com Clinic Scraper](https://apify.com/haketa/whatclinic-scraper) — global clinic directory (US + 100+ countries) for dental, cosmetic, fertility, and elective specialties.
- [Bookimed Medical Tourism Scraper](https://apify.com/haketa/bookimed-scraper) — international medical-tourism clinics, prices, and patient reviews.
- [Texas Pharmacy License Scraper — TSBP](https://apify.com/haketa/tsbp-license-scraper) — every pharmacist, pharmacy, intern, and technician in Texas (cross-reference NPI license numbers).
- [Ohio eLicense Scraper](https://apify.com/haketa/ohio-elicense-scraper) — every Ohio professional license (medical, nursing, pharmacy).
- [California DCA Professional License Scraper](https://apify.com/haketa/california-dca-license-scraper) — California Department of Consumer Affairs healthcare boards.
- [SAM.gov Federal Contractor Entity Scraper](https://apify.com/haketa/sam-gov-federal-contractor-scraper) — federal contractor entity registry for diligence and B2B.

***

### 📋 Changelog

| Version | Date | Updates |
| :--- | :--- | :--- |
| **v1.2** | **2026-11** | **Unlocked 1,000+ deep pagination & auto-sharding:** added automatic US state fan-out and alphabetical (`A*`–`Z*`) prefix sharding whenever a query reaches the registry's 1,200-record (`skip=1000`) ceiling, allowing single runs to scale to 10,000+ unique providers with 0 duplicates. |
| **v1.1** | **2026-11** | Added `authorizedOfficial` decision-maker extraction for NPI-2 organizations, cleaned placeholder tokens (`--`, `.`), and added specialty dropdown + mixed default sample. |
| **v1.0** | **2026-05** | Initial release supporting NPI-1 & NPI-2 provider extraction, taxonomy/license normalization, and multi-state query matrices. |

# Changelog

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

# Actor input Schema

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

Pick a provider specialty. This is the fastest way to pull a targeted provider list. Leave blank to search by name/organization instead, or leave the whole form empty for a mixed sample.

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

Optional. Type any CMS taxonomy / specialty phrase not in the dropdown above (partial match works, e.g. 'Neurology', 'Oncology', 'Acupuncturist'). Overrides the dropdown when set.

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

Pick one or more US states / territories to narrow results. Note: a state on its own is not enough for the registry — it is automatically paired with the specialty or name/organization you choose.

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

Individual = a person (doctor, nurse, dentist). Organization = a hospital, clinic, or group practice. Choose both to include everything.

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

Optional. Search organizations by name. Examples: 'Mount Sinai', 'Kaiser Permanente', 'Walgreens'. Skip when searching individuals.

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

Optional. Provider first name (partial match). Examples: 'John', 'Sarah'. Best paired with a last name + state.

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

Optional. Provider last name. Best paired with a first name + state for a precise individual lookup.

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

Optional. Narrow to specific cities by name. Examples: 'New York', 'Los Angeles', 'Houston'. Each city runs as a separate query.

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

Optional. Narrow by ZIP. Partial match works (e.g. '100' matches all 100xx ZIPs).

## `npis` (type: `array`):

Optional. Paste 10-digit NPI numbers to look up exact providers directly — the fastest mode. Example: 1982445060. Leave empty to use the filters above.

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

Optional. Which address to match on: Practice location, Mailing address, or a primary/secondary practice site. Leave 'Any' for no filter.

## `maxRecords` (type: `integer`):

Maximum providers to collect across all searches. Set 0 for unlimited. A leave-it-empty run is automatically capped to a fast ~100-record sample.

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

Delay between registry calls. 500-2000ms keeps the run polite and stable.

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

Optional. The CMS NPPES registry is a public API — a proxy is usually not needed.

## Actor input object example

```json
{
  "specialty": "",
  "specialtyCustom": "",
  "states": [],
  "enumerationType": "any",
  "organizationName": "",
  "firstName": "",
  "lastName": "",
  "cities": [],
  "postalCode": "",
  "npis": [],
  "addressPurpose": "any",
  "maxRecords": 100,
  "requestDelay": 800,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `npi` (type: `string`):

10-digit National Provider Identifier

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

NPI-1 individual or NPI-2 organization

## `fullName` (type: `string`):

Provider full name

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

Organization name (NPI-2 only)

## `credential` (type: `string`):

MD / DO / RN / PA / etc.

## `primaryTaxonomyDesc` (type: `string`):

Primary taxonomy / specialty

## `primaryLicense` (type: `string`):

Primary state license number

## `primaryLicenseState` (type: `string`):

Primary license issuing state

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

Location city

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

Location state

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

Location ZIP

## `phone` (type: `string`):

Location phone

## `status` (type: `string`):

Active / Deactivated

## `enumerationDate` (type: `string`):

NPI assignment date

## `scrapedAt` (type: `string`):

ISO timestamp

# 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 = {
    "states": [],
    "organizationName": "",
    "cities": [],
    "npis": [],
    "maxRecords": 100,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/nppes-npi-registry-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 = {
    "states": [],
    "organizationName": "",
    "cities": [],
    "npis": [],
    "maxRecords": 100,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/nppes-npi-registry-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 '{
  "states": [],
  "organizationName": "",
  "cities": [],
  "npis": [],
  "maxRecords": 100,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call haketa/nppes-npi-registry-scraper --silent --output-dataset

```

## MCP server setup

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