# NPI Registry Search - US Doctors & Healthcare Providers (`kantolabs/npi-registry-search`) Actor

Search the official NPPES NPI Registry for US doctors, dentists, nurses, clinics and hospitals by name, specialty (taxonomy), city, state or ZIP code, or look up NPI numbers. Returns clean rows with specialties, licenses, practice and mailing addresses and phone numbers. $2 per 1,000 providers.

- **URL**: https://apify.com/kantolabs/npi-registry-search.md
- **Developed by:** [Kanto Labs](https://apify.com/kantolabs) (community)
- **Categories:** Lead generation, Business, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 provider returneds

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

## NPI Registry Search - US Doctors, Dentists & Healthcare Providers

Search the **official NPPES NPI Registry** (run by CMS, the US Centers for Medicare & Medicaid
Services) and get **clean, ready-to-use rows** for doctors, dentists, nurse practitioners,
therapists, pharmacies, clinics and hospitals: **specialty, license number, practice address,
phone, fax, mailing address, other names and NPI status**.

Search by **specialty** (taxonomy), **city**, **state**, **ZIP code**, **first/last name** or
**organization name**, or paste a list of **NPI numbers** to verify and refresh. **$2 per 1,000
providers.** No API key, no login, no scraping - the data comes straight from the government's
public API.

### What you can use it for

- **Healthcare lead lists** - every dentist in Austin, every cardiology practice in a ZIP code, every pharmacy in a state (split by city or ZIP).
- **NPI verification** - check that a list of NPI numbers is valid and active, and pull the current name, specialty and address.
- **Provider directories and credentialing** - license numbers and states per specialty, organization names and "doing business as" names.
- **Market sizing** - count providers per specialty and area.
- **Data enrichment** - add phone, fax and practice address to a CRM that only has names or NPIs.
- **AI agents** - one tool call through the Apify MCP server answers "find me pediatric dentists in 10001".

### Input

| Field | Example | Notes |
|---|---|---|
| Specialties | `Dentist`, `Cardiology`, `Family Medicine`, `Physical Therapist` | Partial words match. One search per specialty and location. |
| States | `TX` | The registry does not accept a state on its own - add a specialty, city, ZIP or name. |
| Cities | `Austin` | Combined with every state. |
| ZIP codes | `78701` | Used instead of cities. The way to get more than 1,200 results. |
| First / last name | `Jo*`, `Smith` | `*` wildcard after 2 letters. |
| Organization name | `Mayo*` | Clinics, hospitals, pharmacies, groups. |
| Provider type | Individuals / Organizations | NPI-1 or NPI-2. |
| NPI numbers | `1255498432` | Direct lookups. |
| Max providers per search | `50` | The registry returns at most 1,200 records per search. |

An empty input `{}` runs a small sample search (dentists in Austin, TX, 20 results).

```json
{
    "taxonomies": ["Cardiology", "Physical Therapist"],
    "postalCodes": ["10001", "94110"],
    "maxResultsPerSearch": 200,
    "npiNumbers": ["1255498432"]
}
```

### Output

One row per unique provider (duplicates across searches are removed). Real output from a cloud run:

```json
{
  "npi": "1154494250",
  "providerType": "Organization",
  "name": "360 DENTAL CARE P.A.",
  "organizationName": "360 DENTAL CARE P.A.",
  "authorizedOfficial": { "name": "MICHAEL B NUSSBAUM", "credential": "D.D.S.", "title": "President", "phone": "(512) 327-3631" },
  "primarySpecialty": "Dentist, General Practice",
  "primaryTaxonomyCode": "1223G0001X",
  "primaryLicense": "16292",
  "primaryLicenseState": "TX",
  "taxonomies": [
    { "code": "1223G0001X", "description": "Dentist, General Practice", "primary": true, "license": "16292",
      "licenseState": "TX", "taxonomyGroup": "193400000X - Single Specialty Group" }
  ],
  "practiceAddress": { "line1": "3660 STONERIDGE RD STE B101", "line2": null, "city": "AUSTIN", "state": "TX",
                       "postalCode": "78746-7759", "country": "US", "phone": "(512) 327-3631", "fax": "(512) 327-2234" },
  "practicePhone": "(512) 327-3631",
  "practiceFax": "(512) 327-2234",
  "mailingAddress": { "line1": "3660 STONERIDGE RD STE B101", "city": "AUSTIN", "state": "TX", "postalCode": "78746-7759" },
  "otherPracticeLocations": [],
  "otherNames": [ { "type": "Doing Business As", "name": "MICHAEL B. NUSSBAUM D.D.S." } ],
  "status": "Active",
  "enumerationDate": "2006-11-16",
  "lastUpdated": "2020-08-22",
  "npiRegistryUrl": "https://npiregistry.cms.hhs.gov/provider-view/1154494250",
  "search": { "city": "Austin", "state": "TX", "taxonomy_description": "Dentist" }
}
```

Individuals also get `firstName`, `middleName`, `lastName`, `credential` (MD, DDS, NP...),
`gender` and `soleProprietor`. Other fields: `otherIdentifiers` (e.g. Medicaid IDs),
`healthInformationExchange` (Direct messaging endpoints when the provider published them) and
`certificationDate`.

The Console shows a table view (NPI, name, credential, type, specialty, city, state, ZIP, phone,
status); export to CSV, Excel, JSON or connect via API, Make, Zapier or n8n.

### Pricing

**$2 per 1,000 providers** ($0.002 each) plus a tiny actor start fee ($0.00005).

| Providers | Cost |
|---|---|
| 100 | $0.20 |
| 1,000 | $2.00 |
| 10,000 | $20.00 |

You pay only for providers returned. **Searches with no results, invalid or unknown NPI numbers
and registry errors are free** (they appear as rows with an `error` field). Set "Maximum cost per
run" and the actor stops cleanly when it is reached.

### Getting more than 1,200 providers

The NPI Registry API returns at most 1,200 records for a single search. For big areas, split the
search: list the ZIP codes of the city in "ZIP codes" (one search per ZIP), or run one search per
specialty. The log warns you when a search hits the 1,200 cap.

### FAQ

**Where does the data come from?** The NPPES NPI Registry API
(npiregistry.cms.hhs.gov), the official public source. Providers update their own records, so
`lastUpdated` tells you how fresh each row is.

**Does it include emails?** No. The registry does not publish email addresses. It does publish
practice phone and fax numbers.

**Is this legal to use?** CMS publishes NPI Registry data openly (NPPES data dissemination) for
anyone to look up and download. Follow the usual rules for any outreach you do (e.g. TCPA for calls
and texts).

**Can I search by taxonomy code?** Search with the description (`Pediatric Dentistry`); each row
returns the codes.

# Actor input Schema

## `taxonomies` (type: `array`):

Provider specialties as written in the NUCC taxonomy, e.g. `Dentist`, `Cardiology`, `Family Medicine`, `Nurse Practitioner`, `Physical Therapist`, `Pharmacy`. Partial words match (`Family` finds Family Medicine and Nurse Practitioner, Family). One search is run per specialty and location.

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

Two-letter US state codes (`TX`, `NY`). The registry does not accept a state on its own - combine it with a specialty, name, city or ZIP code.

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

City names (`Austin`). Combined with every state above.

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

5-digit ZIP codes (`78701`). When given, they are used instead of cities. Searching ZIP by ZIP is the way to collect more than 1,200 providers for one specialty in a big city.

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

Individual provider's first name. Add `*` after at least 2 letters for a prefix search (`Jo*`).

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

Individual provider's last name. `*` wildcard allowed after 2 letters.

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

Clinic, hospital, pharmacy or group name, e.g. `Mayo*`. `*` wildcard allowed after 2 letters.

## `providerType` (type: `string`):

Individuals (NPI-1: doctors, dentists, nurses...) or organizations (NPI-2: clinics, hospitals, pharmacies, groups).

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

10-digit NPI numbers. Each is looked up directly (in addition to any search above). Use this to verify or refresh a list you already have.

## `maxResultsPerSearch` (type: `integer`):

Cap per specialty x location combination. The registry itself returns at most 1,200 records for one search (200 per page, 6 pages) - split by ZIP code to get more.

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

Stop after this many unique providers across all searches. 0 = no limit.

## Actor input object example

```json
{
  "taxonomies": [
    "Dentist"
  ],
  "states": [
    "TX"
  ],
  "cities": [
    "Austin"
  ],
  "providerType": "any",
  "maxResultsPerSearch": 50,
  "maxResults": 0
}
```

# Actor output Schema

## `results` (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 = {
    "taxonomies": [
        "Dentist"
    ],
    "states": [
        "TX"
    ],
    "cities": [
        "Austin"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kantolabs/npi-registry-search").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 = {
    "taxonomies": ["Dentist"],
    "states": ["TX"],
    "cities": ["Austin"],
}

# Run the Actor and wait for it to finish
run = client.actor("kantolabs/npi-registry-search").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 '{
  "taxonomies": [
    "Dentist"
  ],
  "states": [
    "TX"
  ],
  "cities": [
    "Austin"
  ]
}' |
apify call kantolabs/npi-registry-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,kantolabs/npi-registry-search"
        }
    }
}
```

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/6J10bFiFGPXcLAhNC/builds/K4BKLf2Jfa77ku9zi/openapi.json
