# NPI Provider Check - NPPES Registry + OIG Exclusion List (LEIE) (`kdhan/npi-provider-check`) Actor

Check US healthcare providers by NPI number or name: NPPES registry status and specialty, plus a match against the HHS-OIG exclusion list (LEIE), with the field behind every risk flag. Official public data, no API key, no phone or address output.

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

## Pricing

from $10.00 / 1,000 provider 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?

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 Provider Check - NPPES Registry + OIG Exclusion List (LEIE)

Check a US healthcare provider or organization before you contract, credential or pay it. Give an
**NPI number** or a **name and state** and get one record per provider, built from two official
public sources: the CMS **NPPES NPI Registry** and the HHS-OIG **List of Excluded
Individuals/Entities (LEIE)**. No scraping, no API key.

This is a verification tool, not a lead list: **phone numbers, fax numbers, street addresses, e-mail
addresses, authorized-official names, gender and dates of birth are deliberately not returned.**

### What you get (one row per provider)

| Section | Fields |
|---|---|
| Identity | `npi`, `enumerationType` (Individual / Organization), `name`, `credential` (e.g. M.D.), `enumerationDate`, `lastUpdated` |
| Status | `status` (Active / Deactivated), `deactivationDate` |
| Specialty | `taxonomies[]`: code, description, primary flag and license state (license numbers are not returned) |
| Location | `practiceLocation`: city, state, 5-digit ZIP only |
| Exclusion check | `leie.checked`, `leie.matches[]` (type, exclusion type code, exclusion date, reinstatement date, general category, specialty, state) |
| Risk flags | `riskFlags` (codes), `riskLevel`, `riskFlagDetails[]` - every flag lists the source and the field/column and value that triggered it |
| Freshness | `dataAsOf.nppes` (time of the query), `dataAsOf.leie` (last update of the OIG file), `disclaimer` |

#### Risk flags

| Flag | Severity | Rule |
|---|---|---|
| `EXCLUDED_NPI_MATCH` | high | The NPI appears on the OIG exclusion list. Evidence: `EXCLTYPE`, `EXCLDATE`, `REINDATE` of every matching row. |
| `POSSIBLE_EXCLUSION_NAME_MATCH` | low | Only for OIG rows that carry **no NPI**: exact last + first name (or organization name) and a state of the provider's practice location match. **This can be a different person with the same name** - confirm it on the OIG online search with an SSN/EIN. |
| `EXCLUSION_REINSTATED` | low | A matching OIG row shows a reinstatement date. |
| `NPI_DEACTIVATED` | medium | NPPES reports the NPI as deactivated (see limits below). |
| `NEWLY_ENUMERATED` | low | The NPI was issued less than 90 days ago. |
| `PARTIAL_DATA` | - | A source could not be queried; the result is incomplete. |

A flag is a reason to look closer, not a verdict. `riskLevel` is `high` when an NPI match is
confirmed (even if another source failed), otherwise `unknown` if a source failed, then `medium`
or `low`. An OIG row that has an NPI different from the provider's is never treated as a name match.

#### No silent failures

- An input that matches nothing is returned as `found: false` with a `reason` (not charged).
- If NPPES could not be queried, the row has `found: null` and an `error` - it does **not** claim the
  provider does not exist. The OIG check still runs on the NPI.
- If the OIG file could not be downloaded, `leie.checked` is `false`, `sectionErrors.leie` explains
  why and `PARTIAL_DATA` is raised. A missing check is never reported as "not excluded".
- `found: false` rows still carry the OIG result for the NPI: excluded providers often have a
  deactivated NPPES record, which the Registry does not return.

### Input

```json
{
  "npiNumbers": ["1134262819"],
  "providers": [
    {"firstName": "Jane", "lastName": "Doe", "state": "MD"},
    {"organizationName": "Johns Hopkins Hospital", "state": "MD"}
  ],
  "maxResultsPerName": 5
}
```

All fields are optional. With an empty input the Actor checks an example hospital (NPI 1134262819).
NPIs are validated locally (10 digits and the NPI check digit); invalid ones are returned as
`found: false` without a lookup. Name searches return only records whose name matches exactly
(organization names match by prefix); `maxResultsPerName` is 1-20. A malformed input (for example
`npiNumbers` that is not an array) fails the run with an English error message.

### Pricing

Pay-per-event, event name `provider-record` (one provider record returned). Inputs that are not
found, or that fail, are not charged. Price: **$0.01 per record** plus a $0.005 start fee.

### Data sources

- **NPPES NPI Registry API v2.1** (`npiregistry.cms.hhs.gov/api`), queried live with a pause between
  requests and exponential back-off on throttling or server errors. NPPES publishes no numeric rate
  limit ("limited per hour"); for bulk work CMS points to its downloadable file, so this Actor is meant
  for lists of tens or hundreds of providers, not millions.
- **HHS-OIG LEIE** downloadable database (`oig.hhs.gov/exclusions/downloadables/UPDATED.csv`),
  downloaded at the start of every run (about 11 MB) and matched in memory. OIG refreshes it monthly
  (see `dataAsOf.leie`). Date of birth and address columns are discarded while reading the file.

### Limits

- The NPI Registry does **not return deactivated or never-issued NPIs**. Such an NPI is reported as
  `found: false`; `NPI_DEACTIVATED` can only appear if NPPES ever returns a deactivated record. In a
  sample of OIG-excluded NPIs, about one in ten was not returned for this reason - the OIG match is
  still reported on the `found: false` row.
- The LEIE file lists exclusions currently in effect; reinstated providers are removed from it, so a
  non-match cannot distinguish "never excluded" from "reinstated".
- The downloadable OIG file has no SSN/EIN. Name matches are candidates only.
- An NPI does not verify that a provider is licensed or credentialed.
- NPPES data is self-reported by providers. NPPES and LEIE public data, provided for informational
  purposes only; not legal advice; verify with CMS/OIG before relying on it.

# Actor input Schema

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

10-digit National Provider Identifiers, for example 1134262819.

## `providers` (type: `array`):

Objects like {"firstName": "Jane", "lastName": "Doe", "state": "MD"} for people or {"organizationName": "Johns Hopkins Hospital", "state": "MD"} for organizations. Only exact name matches are returned (organization names match by prefix).

## `maxResultsPerName` (type: `integer`):

Upper limit of provider records returned for each name search. You are charged per provider record returned.

## Actor input object example

```json
{
  "npiNumbers": [
    "1134262819"
  ],
  "maxResultsPerName": 5
}
```

# Actor output Schema

## `providers` (type: `string`):

NPPES identity and status, taxonomy and license state, OIG exclusion matches, risk flags with evidence, data freshness and disclaimer.

# 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 = {
    "npiNumbers": [
        "1134262819"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("kdhan/npi-provider-check").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 = { "npiNumbers": ["1134262819"] }

# Run the Actor and wait for it to finish
run = client.actor("kdhan/npi-provider-check").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 '{
  "npiNumbers": [
    "1134262819"
  ]
}' |
apify call kdhan/npi-provider-check --silent --output-dataset

```

## MCP server setup

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

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/tpgLPnTfy8M9BIK4F/builds/dthz6jwjrkzrYtdcj/openapi.json
