# NPI Registry lookup - healthcare providers (NPPES API) (`retrainmap/npi-provider-registry`) Actor

Healthcare providers from the CMS NPI Registry (NPPES API 2.1): look up NPI numbers or search by taxonomy, name, organization, city, state, ZIP and NPI type. One flat row per provider: name, credential, primary taxonomy and license, practice and mailing address, phone, dates, status.

- **URL**: https://apify.com/retrainmap/npi-provider-registry.md
- **Developed by:** [RetrainMap Team](https://apify.com/retrainmap) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 records

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?

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 lookup — healthcare providers (NPPES API)

One flat row per healthcare provider from the CMS **National Plan and Provider Enumeration
System (NPPES) NPI Registry**, read live through its public API (version 2.1). Look up a list
of NPI numbers, or search by taxonomy (specialty), first/last name, organization name, city,
state, postal code and NPI type; get name, credential, primary taxonomy with license number and
state, other taxonomies, practice and mailing address, phone, enumeration and update dates and
status — flattened and cleaned (the registry's `--` placeholders become nulls, ZIP+4 is
hyphenated).

**Honesty note.** The NPI Registry is a public directory of enumerated providers with
self-reported details. A row means an NPI exists with these details — it is not a
credentialing verdict: it does not establish that the provider is licensed, in good standing,
or enrolled with any payer. Verify with the state licensing board or the payer.

### Data source and status

| | |
|---|---|
| Publisher | Centers for Medicare & Medicaid Services (CMS), NPPES |
| API | `https://npiregistry.cms.hhs.gov/api/?version=2.1` — plain GET, no key, JSON; documentation at https://npiregistry.cms.hhs.gov/api-page |
| Bulk file of record | Monthly NPPES data dissemination file: https://download.cms.gov/nppes/NPI\_Files.html |
| Refresh cadence | The registry is updated continuously as providers file changes (weekly incremental files, monthly full file). The Actor reads live on every run; `fetched_at` is the fetch time and `last_update_date` is the record's own date |
| Copyright | Works of the United States Government are not subject to copyright in the U.S. (17 U.S.C. §105). The data are public; please cite CMS/NPPES as the source |
| CMS limits (measured 2026-09-04) | At most 200 results per request (`limit`; 201 is silently served as 200) and `skip` is clamped at 1,000 (skip 1001 and 1400 return the skip-1000 page), so **one search returns at most 1,200 providers** — narrow the criteria (city, postal code, NPI type) to see more. `result_count` is the page count, not the total. A search by state alone, or by NPI type alone, is refused by the registry. `city`/`state`/`postal_code` match the practice **or** the mailing address (a Raleigh search also returns providers practising in Durham or Cary whose mailing address is in Raleigh) — filter on `practice_city` if you need the practice location only |

Identification: requests carry the product-token User-Agent
`RetrainMap-npi-provider-registry/0.1` and the operator's contact address in the standard
`From:` header. Rate: one request per 500 ms by default (floor 250 ms), retries on 429/5xx.

### Input

| Field | Type | Meaning |
|---|---|---|
| `npi_numbers` | array of 10-digit strings | **Lookup mode**: one request per number; search criteria are ignored. Numbers with a wrong check digit stop the run; valid-but-unknown numbers are listed as `not_found` in the run summary |
| `taxonomy_description` | string | **Search mode** (all criteria AND-ed). E.g. `Physical Therapist`, `Family Medicine`; trailing `*` wildcard after two characters. Matches any of the provider's taxonomies |
| `first_name`, `last_name` | string | Individuals; trailing `*` wildcard |
| `organization_name` | string | Organizations; trailing `*` wildcard |
| `city`, `state`, `postal_code` | string | `state` is a two-letter code; `postal_code` 5 or 9 digits, trailing `*` wildcard |
| `enumeration_type` | `any` / `NPI-1` / `NPI-2` | Individual (NPI-1) or organization (NPI-2) |
| `max_records` | integer | Default 200 (Console prefill 100). Searches stop at 1,200 regardless |
| `request_interval_ms` | integer | Default 500 (floor 250) |
| `contact_email` | string | Sent in the `From:` header |

Examples — physical therapists in Raleigh, NC (the default input, ~100 rows):

```json
{ "taxonomy_description": "Physical Therapist", "state": "NC", "city": "Raleigh", "max_records": 100 }
```

Three known NPIs:

```json
{ "npi_numbers": ["1922739051", "1972760981", "1003000126"] }
```

### Output (dataset row)

`npi`, `enumeration_type` (`NPI-1`/`NPI-2`), `entity` (`individual`/`organization`), `name`
(organization name, or prefix + first + middle + last + suffix), `first_name`, `last_name`,
`credential`, `gender`, `sole_proprietor` (individuals), `authorized_official`,
`authorized_official_title` (organizations), `primary_taxonomy_code`, `primary_taxonomy`,
`primary_license_number`, `primary_license_state`, `other_taxonomies` (`code desc; code desc`),
`taxonomy_count`, `practice_address_1`, `practice_address_2`, `practice_city`,
`practice_state`, `practice_zip`, `practice_country`, `practice_phone`, `practice_fax`,
`mailing_city`, `mailing_state`, `mailing_zip`, `additional_practice_locations` (count of
secondary practice locations on file), `enumeration_date`, `last_update_date`,
`certification_date`, `status` (`A` = active), `deactivation_date`, `fetched_at`, `source`.

A run summary (mode, criteria, request count, `not_found` NPIs, whether the CMS 1,200 cap or
the pay-per-event budget stopped the run) is stored as `RUN_SUMMARY` in the run's key-value
store.

### Pricing (pay per event)

| Event | Price |
|---|---|
| `run-start` — once per run | $0.10 |
| `record` — per row written | $0.005 |

The default 100-row search costs $0.60; a full 1,200-row search $6.10; a 500-number lookup
$2.60. Rows stop when your run's maximum charge is reached; the run summary says so.

### Operator

Steelyard Ventures LLC (RetrainMap) — info@steelyardclinical.com. The Actor writes only to
its own dataset and key-value store; it stores no credentials and sends nothing else.

# Actor input Schema

## `npi_numbers` (type: `array`):

Ten-digit NPI numbers to look up, one request each. When this list is non-empty the search criteria below are ignored. Numbers that fail the NPI check digit stop the run; numbers that are valid but unknown to the registry are listed in the run summary as not\_found.

## `taxonomy_description` (type: `string`):

Healthcare Provider Taxonomy description, e.g. Physical Therapist, Family Medicine, Dentist, Pharmacy. Exact or with a trailing \* wildcard (e.g. Physical Ther\*). Matches any of the provider's taxonomies, not only the primary one.

## `first_name` (type: `string`):

Provider first name; trailing \* wildcard allowed after two characters.

## `last_name` (type: `string`):

Provider last name; trailing \* wildcard allowed after two characters.

## `organization_name` (type: `string`):

Organization legal or other name; trailing \* wildcard allowed after two characters.

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

City of the practice location or mailing address.

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

Two-letter state or territory code (NC, TX, PR). The registry refuses a search by state alone - combine it with at least one other criterion.

## `postal_code` (type: `string`):

Five- or nine-digit ZIP; a trailing \* wildcard is allowed after two characters (e.g. 276\*).

## `enumeration_type` (type: `string`):

NPI-1 = individual provider, NPI-2 = organization. The registry requires at least one other criterion together with the type.

## `max_records` (type: `integer`):

Stop after this many provider rows. Searches are capped at 1,200 results by CMS whatever you enter here (limit 200 per request, skip clamped at 1,000); lookups by number are limited only by this value.

## `request_interval_ms` (type: `integer`):

Politeness delay towards npiregistry.cms.hhs.gov. Default 500 ms; the floor is 250 ms.

## `contact_email` (type: `string`):

Sent in the standard From: request header next to the Actor's User-Agent so the data owner can reach the operator (RFC 9110 s10.1.2).

## Actor input object example

```json
{
  "taxonomy_description": "Physical Therapist",
  "city": "Raleigh",
  "state": "NC",
  "enumeration_type": "any",
  "max_records": 100,
  "request_interval_ms": 500,
  "contact_email": "info@steelyardclinical.com"
}
```

# Actor output Schema

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

One row per provider: NPI, type, name, credential, primary taxonomy and license, other taxonomies, practice and mailing address, phone, dates, status.

## `results_csv` (type: `string`):

The same rows as a CSV file.

# 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 = {
    "taxonomy_description": "Physical Therapist",
    "city": "Raleigh",
    "state": "NC",
    "max_records": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("retrainmap/npi-provider-registry").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 = {
    "taxonomy_description": "Physical Therapist",
    "city": "Raleigh",
    "state": "NC",
    "max_records": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("retrainmap/npi-provider-registry").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 '{
  "taxonomy_description": "Physical Therapist",
  "city": "Raleigh",
  "state": "NC",
  "max_records": 100
}' |
apify call retrainmap/npi-provider-registry --silent --output-dataset

```

## MCP server setup

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

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/3AQzUw7AMZY1lV6NR/builds/voGj60b2hJe2yubsN/openapi.json
