# Physician Directory + NPI Cross-Reference (`george.the.developer/physician-directory-npi`) Actor

Cross-reference NPI Registry plus state medical license boards into one verified physician contact record. Built for healthcare M\&A brokers, PE rollups, physician recruiters. Pay per result.

- **URL**: https://apify.com/george.the.developer/physician-directory-npi.md
- **Developed by:** [George Kioko](https://apify.com/george.the.developer) (community)
- **Categories:** Lead generation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event + usage

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## Physician Directory + NPI Cross-Reference

Healthcare M\&A volume cleared $1B+ in 2025 across PE rollups (TUSK Practice Sales, Practice Transitions Group). DSO deal flow alone was 10+ practices/month in September 2025. Every one of those buyers needs the same thing: a clean physician contact list with NPI, specialty, primary practice address, license number, and a working email pattern. This actor returns that record on demand at per-call pricing.

[![Apify Store](https://img.shields.io/badge/Apify-Store-blue)](https://apify.com/george.the.developer/physician-directory-npi)
[![Pricing](https://img.shields.io/badge/Pricing-PAY_PER_EVENT-green)](https://apify.com/george.the.developer/physician-directory-npi)

### Why this exists

Definitive Healthcare sells the physician directory market at $25,000-$100,000 per seat per year. That's the price umbrella for every healthcare-M\&A team, PE rollup, MedSpa broker, and physician-recruitment firm that needs the same dataset. The NPI Registry has been free public data from CMS since 2007. Healthgrades, Vitals, and ZocDoc are public-web. State medical license boards are searchable in every US state. The data is there. Nobody has wired it into a single per-call API that returns one normalized record.

This actor does that. NPI Registry as the spine. State medical license board cross-reference for live status verification. Email guess generator for outreach. One call, one record, $0.05-$0.25 per row depending on enrichment level.

### How it works

```
              /search?specialty=&state=             /enrich?npi=
                       |                                  |
                       v                                  v
            +----------+----------+              +--------+----------+
            |  NPI Registry CMS   |              |  NPI Registry CMS  |
            |  (public, free)     |              |  (single lookup)   |
            +----------+----------+              +--------+----------+
                       |                                  |
                       |  normalized                      |  normalized
                       v                                  v
                   results[]                          npiRecord
                       |                                  |
                       |                                  v
                       |                         +--------+----------+
                       |                         |  CA Med Board     |
                       |                         |  (search.dca.ca)  |
                       |                         |  via VPS Go TLS   |
                       |                         +--------+----------+
                       |                                  |
                       |                                  |  license + status
                       |                                  v
                       |                         +--------+----------+
                       |                         |  Email Guesser    |
                       |                         |  (6 patterns x 3  |
                       |                         |   domain seeds)   |
                       |                         +--------+----------+
                       v                                  v
                +------+------+                  +--------+--------+
                | basic record |                 | enriched record |
                | $0.05/row    |                 | $0.25/row       |
                +-------------+                  +-----------------+
```

### Endpoints

| Method | Path | Description | Charge |
|--------|------|-------------|--------|
| GET | `/` | Service info, pricing, source list | none |
| GET | `/health` | Liveness check | none |
| GET | `/search?specialty=&state=&city=&limit=` | Search NPI Registry, return basic records | $0.05 per result |
| GET | `/enrich?npi=` | Single NPI -> full enrichment | $0.25 per record |
| GET | `/enrich?name=&state=` | Name + state -> NPI lookup -> enrichment | $0.25 per record |
| POST | `/enrich/bulk` body `{npis:[...]}` (max 25) | Bulk enrichment | $0.25 per record |

### Quick start

```bash
## Search by specialty + state
curl -s "https://george-the-developer--physician-directory-npi.apify.actor/search?specialty=Cardiology&state=CA&limit=10" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN"

## Enrich a single NPI
curl -s "https://george-the-developer--physician-directory-npi.apify.actor/enrich?npi=1710071717" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN"

## Bulk enrich (max 25 NPIs)
curl -s -X POST "https://george-the-developer--physician-directory-npi.apify.actor/enrich/bulk" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"npis":["1710071717","1528076718","1962778159"]}'
```

### Sample response

```json
{
  "ok": true,
  "record": {
    "npi": "1710071717",
    "name": "ABDUL SATTAR ABBASI",
    "credentials": "MD",
    "specialty": "Internal Medicine, Cardiovascular Disease",
    "specialty_group": "Other",
    "taxonomy_code": "207RC0000X",
    "primary_address": {
      "street": "1045 ATLANTIC AVE, SUITE 912",
      "city": "LONG BEACH",
      "state": "CA",
      "zip": "908133408",
      "phone": "562-437-2801",
      "fax": ""
    },
    "license": {
      "state": "CA",
      "license_number": "A24632",
      "status": "unknown",
      "note": "Cross-referenced from NPI taxonomy. Verify live status at search.dca.ca.gov if critical."
    },
    "email_guesses": [
      { "email": "abdul.abbasi@abbasimd.com", "verified": false },
      { "email": "aabbasi@abbasimd.com", "verified": false },
      { "email": "abdul.abbasi@abbasiinternalmedicine.com", "verified": false }
    ],
    "enumeration_date": "2010-06-01",
    "last_updated": "2024-12-01",
    "status": "A",
    "source": {
      "npi_registry": "https://npiregistry.cms.hhs.gov/api/?version=2.1&number=1710071717",
      "state_license_board": "https://search.dca.ca.gov/results?BOARDCODE=8002&LICENSETYPE=A&..."
    }
  }
}
```

### Pricing

| Event | Price | What you get |
|-------|-------|--------------|
| `apify-actor-start` | $0.10 per run (per GB memory) | Standby instance warm |
| `physician-discovered` | $0.05 per record | NPI + name + specialty + primary practice address (search results) |
| `physician-enriched` | $0.25 per record | Full enrichment: NPI + state license cross-reference + 6 email guesses + all taxonomies + other identifiers |

For comparison: Definitive Healthcare seats run $25K-$100K/yr. At $0.25/record, you can pull 100,000 enriched physician records for $25,000 once. That's the price umbrella this is sitting under.

### Use cases

- **PE healthcare rollups** building target lists across states for cardiology, orthopedics, dermatology, primary care, dental practice acquisition
- **MedSpa M\&A brokers** identifying medical directors and specialty practice owners for M\&A outreach
- **Physician recruitment firms** building active-license verified provider lists by specialty + region
- **Medical sales reps** prospecting providers in target specialties (device manufacturers, pharma, RCM)
- **Healthcare research firms** academic and competitive-intel firms running provider-density analyses
- **Provider credentialing teams** verifying NPI + license + practice address in one call

### Honest tradeoffs (v1)

- **State license live status:** v1 wires CA Medical Board (search.dca.ca.gov) live cross-reference. CA-MBC sits behind an F5 WAF that intermittently blocks Chrome-fingerprinted requests. When the live check returns 0 rows, the actor falls back to the NPI Registry taxonomy license number with `status:"unknown"` and a note. FL, NY, TX coming in v2.
- **Healthgrades / Vitals / ZocDoc:** deferred to v2. Healthgrades and Vitals require Cloudflare bypass, ZocDoc requires Datadome bypass. Adding them is the work for v2 once the v1 dataset proves the demand.
- **Email guessing:** the 6 patterns generated are *unverified guesses*. The note on each guess says so. Pair them with my [Email Validator API](https://apify.com/george.the.developer/email-validator-api) for SMTP-grade verification before sending outreach.
- **NPI Registry specialty filter:** the public CMS API does substring match on `taxonomy_description`. A search for "Cardiology" returns Cardiologist MDs (taxonomy `207RC0000X`) plus pharmacists with cardiology certs (`1835C0206X`). Filter by `taxonomy_code` prefix `207RC` for MD-only cardiologists.
- **Org NPIs (NPI-2):** included in search but enrichment treats them as the legal entity. For physician-level outreach, filter by `enumeration_type:"NPI-1"`.

### Test-payload short-circuit

Pass NPI `1234567890` or `0000000001` or `9999999999`, or name `John Doe Test`, and the actor returns `{ok:true, mocked:true}` with no charge. Use these for CI smoke tests without burning credit.

```bash
curl -s "https://george-the-developer--physician-directory-npi.apify.actor/enrich?_test=true&npi=0000000001" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN"
## {"ok":true,"mocked":true,"reason":"test-payload short-circuit, NPI Registry skipped"}
```

### More from this developer

- [Email Validator API](https://apify.com/george.the.developer/email-validator-api) — pair with email guesses for SMTP verification ($0.002 per check)
- [Domain WHOIS Lookup](https://apify.com/george.the.developer/domain-whois-lookup) — pull practice domain registration ($0.005 per domain)
- [Company Enrichment API](https://apify.com/george.the.developer/company-enrichment-api) — full company profile from a domain ($0.01 per company)
- [Obituary Life-Insurance Lead Scraper](https://apify.com/george.the.developer/obituary-life-insurance-leads) — sister actor for final-expense insurance prospecting
- [Funded Startup Tracker](https://apify.com/george.the.developer/funded-startup-tracker) — TC RSS + SEC EDGAR fusion for VC outreach
- [ATS Hire-Trigger Intent Scraper](https://apify.com/george.the.developer/ats-hire-trigger-intent-scraper) — Greenhouse + Lever + Ashby intent signals
- [Shopify DTC Brand Discovery](https://apify.com/george.the.developer/shopify-dtc-brand-discovery) — DTC brand finder + Klaviyo tech-stack detection

Built by George The Developer. Source-of-record at [github.com/the-ai-entrepreneur-ai-hub/physician-directory-npi-docs](https://github.com/the-ai-entrepreneur-ai-hub/physician-directory-npi-docs).

# Actor input Schema

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

Specialty / taxonomy keyword, e.g. 'Cardiology', 'Internal Medicine', 'Dermatology'.

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

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

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

Optional city filter, used for NPI Registry city query.

## `limit` (type: `integer`):

Maximum records per search (1-200).

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

10-digit NPI for /enrich. Looks up the provider in NPI Registry, then cross-references state license board.

## `name` (type: `string`):

Optional: 'First Last' for /enrich when no NPI is supplied. Combine with state for best results.

## `enrichment` (type: `string`):

'basic' returns NPI + name + specialty + primary address only. 'full' adds state license cross-reference + email guesses.

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

Optional: array of NPI numbers to enrich in bulk (max 25)

## Actor input object example

```json
{
  "specialty": "Cardiology",
  "state": "CA",
  "limit": 20,
  "npi": "1982227625",
  "enrichment": "full"
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("george.the.developer/physician-directory-npi").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("george.the.developer/physician-directory-npi").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call george.the.developer/physician-directory-npi --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=george.the.developer/physician-directory-npi",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/Py1RZFFOczu63t6e0/builds/KyMFUjmyoVcFa4Oek/openapi.json
