If you've ever needed to look up a doctor's NPI number, verify a provider's credentials, or build a list of specialists in a given area, you've probably used the NPPES website. And you've probably noticed it's awful.
The search is slow, the results are paginated one painful page at a time, there's no bulk export, and the interface looks like it hasn't been updated since 2008. Which it might not have been.
The good news: there's a free public API behind it that's actually pretty decent. The bad news: the docs are scattered and the response format is... a lot.
What's in the NPI Registry?
Every healthcare provider in the US that bills insurance has a National Provider Identifier -- a 10-digit number assigned by CMS. The NPPES registry has over 7 million active records.
For individual providers (doctors, nurses, therapists, dentists), you get:
- Full name and credentials (MD, DO, NP, LCSW, etc.)
- Primary specialty and all taxonomy codes
- Practice address and phone number
- Mailing address
- License numbers by state
- Enumeration date (when they got their NPI)
For organizations (hospitals, clinics, group practices), you get the organization name, authorized official, address, specialties, and the same taxonomy data.
Who actually needs this data?
More people than you'd think. I've talked to folks in healthcare sales, credentialing, insurance verification, and compliance who all need NPI lookups at scale. A few common use cases:
Healthcare sales teams building prospect lists of cardiologists in Texas or dentists in the Bay Area. The NPI registry is basically a free healthcare provider directory with verified contact info.
Credentialing departments verifying that a provider is active, has the right specialty, and practices where they say they do. Manual lookups on the NPPES site take forever when you're processing hundreds of applications.
Insurance companies and billing teams validating NPI numbers on claims. A wrong NPI means a rejected claim, and nobody wants to chase that down manually.
Researchers studying provider distribution, specialty density by geography, or healthcare access patterns. The data is rich enough for serious analysis if you can get it in bulk.
The NPPES API
CMS runs a free API at https://npiregistry.cms.hhs.gov/api/. No API key needed, no authentication, no signup. Just hit the endpoint.
Here's a basic search for internal medicine doctors named Smith in California:
GET https://npiregistry.cms.hhs.gov/api/?version=2.1&first_name=Smith&enumeration_type=NPI-1&state=CA&taxonomy_description=Internal%20Medicine&limit=50
The response is JSON with a results array. Each result has nested objects for basic info, addresses, taxonomies, and other names.
The catch: the API maxes out at 200 results per request, and there's no cursor or offset pagination. If your query matches more than 200 providers, you need to narrow your search (add city, postal code, etc.) or break it into multiple requests.
Also, the response structure is deeply nested. Addresses come in an array with different address_purpose values ("LOCATION" vs "MAILING"). Taxonomies are another array where you need to find the one with primary: true. It's not hard, but it's tedious to flatten into something usable.
The easy way
I built a tool that wraps the NPPES API, handles the pagination workaround, flattens the nested response into clean records, and exports to CSV/JSON/Excel:
NPPES NPI Lookup - Healthcare Provider Search
You search by name, NPI number, specialty, city, state, or ZIP code. It returns flat records with the fields you actually care about -- name, credential, specialty, practice address, phone, NPI, status.
What it does that the raw API doesn't
- Handles the 200-result limit by breaking large queries into smaller geographic chunks
- Flattens the nested response so you get one row per provider with clean columns
- Returns up to 10,000 results per run
- Exports directly to CSV, JSON, or Excel -- no post-processing needed
Example: find all cardiologists in Houston
Set search type to "Individual Provider," leave name blank, set specialty to "Cardiology," city to "Houston," state to "TX." Run it. You get a clean spreadsheet of every cardiologist in Houston with their NPI, practice address, phone number, and credentials.
Pricing
$0.005 per result + $0.10 per run. 1,000 provider records costs about $5.10. No subscription, no monthly minimum.
Tips if you're building your own
If you want to hit the API directly, a few things that tripped me up:
The taxonomy_description field is fuzzy-matched. Searching for "cardio" returns Cardiology, Cardiovascular Disease, Cardiovascular Surgery, etc. This is actually useful for discovery but annoying when you want exact matches.
Use enumeration_type to filter. NPI-1 is individual providers, NPI-2 is organizations. If you don't specify, you get both mixed together.
The limit parameter caps at 200. And there's no skip or offset. If you need more than 200 results, you have to subdivide your search. State + city combinations work well for this.
Rate limiting is generous but undocumented. I've hit it at around 2-3 requests per second. Adding a small delay between requests keeps things stable. The API doesn't return rate limit headers, so you won't know you're hitting the limit until requests start failing.
Watch for deactivated NPIs. Some records have status: "D" (deactivated). If you're building a prospect list or doing credentialing verification, filter these out.
Bulk download alternative
CMS also publishes a monthly full export of the NPI registry as a CSV file. It's about 8GB uncompressed. If you need the entire dataset and don't mind working with a massive file, that's at https://download.cms.gov/nppes/NPI_Files.html.
For most use cases though, searching by criteria is more practical than downloading 7 million records and filtering locally.
If you're doing healthcare provider lookups at scale, try the NPI Lookup tool on Apify. Questions or feature requests -- hit me up on the Apify Discord or open an issue on the actor page.
Top comments (0)