DEV Community

easysolutions906
easysolutions906

Posted on

How to Verify Healthcare Provider NPI Numbers in Your Application

How to Verify Healthcare Provider NPI Numbers in Your Application

Every healthcare provider in the United States has a National Provider Identifier -- a unique 10-digit number issued by CMS through the National Plan and Provider Enumeration System (NPPES). If you are building a credentialing platform, an insurance verification system, a provider directory, or a telehealth application, you need to verify NPI numbers against the live registry. An invalid or mismatched NPI can delay claims, trigger audits, and in the worst case indicate fraud.

This article covers why NPI verification matters, the three main use cases, and how to integrate it into your application.

Why NPI verification matters

Credentialing

When a healthcare organization onboards a new provider, they must verify the provider's NPI, confirm their specialty taxonomy, and check their practice address. Manual verification through the NPPES website is slow and error-prone. Automating NPI lookups during the credentialing workflow reduces onboarding time from days to minutes.

Insurance and claims

Every claim submitted to a payer includes the rendering provider's NPI. If the NPI does not match the provider's name and taxonomy in the NPPES registry, the claim gets rejected. Pre-validating NPI data before claim submission catches these mismatches early.

Fraud prevention

Fraudulent providers use fabricated or stolen NPI numbers. Verifying that an NPI is active, belongs to the claimed individual, and has the expected specialty is a basic fraud control. Some states now require NPI verification as part of Medicaid enrollment.

Looking up an NPI by number

The simplest use case: you have a 10-digit NPI and need to verify it is real and get the provider's details.

curl "https://npi-lookup.up.railway.app/lookup?number=1629067153"
Enter fullscreen mode Exit fullscreen mode

Response:

{
  "npi": "1629067153",
  "type": "individual",
  "firstName": "John",
  "lastName": "Smith",
  "credential": "M.D.",
  "gender": "Male",
  "status": "Active",
  "addresses": [
    {
      "type": "practice",
      "line1": "123 Medical Center Dr",
      "city": "Dallas",
      "state": "TX",
      "zip": "752301234",
      "phone": "2145551234"
    }
  ],
  "taxonomies": [
    {
      "code": "207R00000X",
      "description": "Internal Medicine",
      "primary": true,
      "state": "TX",
      "license": "MD12345"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

This gives you everything you need: the provider's name, credential, practice address, specialty, and license number -- all from the live NPPES registry.

Searching for providers

When you need to find providers by name, specialty, or location rather than by NPI number:

curl "https://npi-lookup.up.railway.app/search?last_name=Smith&state=TX&taxonomy_description=Cardiology&limit=5"
Enter fullscreen mode Exit fullscreen mode

This queries the live CMS NPPES API and returns formatted results. Useful for provider directory searches, referral lookups, and network adequacy reporting.

Integrating NPI verification into your credentialing flow

Here is a JavaScript implementation for verifying a provider during onboarding:

const verifyProvider = async (npiNumber, expectedName, expectedTaxonomy) => {
  const res = await fetch(
    `https://npi-lookup.up.railway.app/lookup?number=${npiNumber}`
  );
  const provider = await res.json();

  if (provider.error) {
    return { verified: false, reason: 'NPI not found in NPPES registry' };
  }

  // Check name match
  const nameMatch =
    provider.lastName?.toLowerCase() === expectedName.lastName.toLowerCase() &&
    provider.firstName?.toLowerCase() === expectedName.firstName.toLowerCase();

  if (!nameMatch) {
    return {
      verified: false,
      reason: `Name mismatch: NPI belongs to ${provider.firstName} ${provider.lastName}`,
    };
  }

  // Check specialty
  const taxonomyMatch = provider.taxonomies?.some(
    (t) => t.description.toLowerCase().includes(expectedTaxonomy.toLowerCase())
  );

  if (!taxonomyMatch) {
    return {
      verified: false,
      reason: `Specialty mismatch: provider taxonomies are ${provider.taxonomies.map((t) => t.description).join(', ')}`,
    };
  }

  return {
    verified: true,
    provider: {
      npi: provider.npi,
      name: `${provider.firstName} ${provider.lastName}, ${provider.credential}`,
      specialty: provider.taxonomies.find((t) => t.primary)?.description,
      address: provider.addresses.find((a) => a.type === 'practice'),
      license: provider.taxonomies.find((t) => t.primary)?.license,
    },
  };
};

// During credentialing
const result = await verifyProvider(
  '1629067153',
  { firstName: 'John', lastName: 'Smith' },
  'Internal Medicine'
);

if (!result.verified) {
  console.log(`Verification failed: ${result.reason}`);
  await flagForManualReview(applicationId, result.reason);
} else {
  console.log(`Verified: ${result.provider.name}`);
  await approveCredentials(applicationId, result.provider);
}
Enter fullscreen mode Exit fullscreen mode

Pre-claim NPI validation

Before submitting a batch of claims, verify all rendering provider NPIs:

const validateClaimNPIs = async (claims) => {
  const results = await Promise.all(
    claims.map(async (claim) => {
      const res = await fetch(
        `https://npi-lookup.up.railway.app/lookup?number=${claim.renderingProviderNPI}`
      );
      const provider = await res.json();

      return {
        claimId: claim.id,
        npi: claim.renderingProviderNPI,
        valid: !provider.error,
        providerName: provider.error
          ? null
          : `${provider.firstName} ${provider.lastName}`,
      };
    })
  );

  const invalid = results.filter((r) => !r.valid);
  if (invalid.length > 0) {
    console.log(`${invalid.length} claims have invalid NPIs:`);
    invalid.forEach((r) => console.log(`  Claim ${r.claimId}: NPI ${r.npi}`));
  }

  return results;
};
Enter fullscreen mode Exit fullscreen mode

Using the MCP server for ad-hoc lookups

The healthcare MCP server includes NPI lookup alongside ICD-10, NDC, and DEA tools. Install for Claude Desktop:

{
  "mcpServers": {
    "healthcare": {
      "command": "npx",
      "args": ["-y", "@easysolutions906/mcp-healthcare"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Ask Claude: "Look up NPI 1629067153 and tell me the provider's specialty and practice address." This is useful for credentialing staff who need quick lookups without navigating the NPPES website.

Compared to the NPPES API directly

You can query https://npiregistry.cms.hhs.gov/api/ directly. The NPI Lookup API wraps it with a cleaner response format, consistent error handling, and formatted address and taxonomy structures. If you are already calling NPPES directly and are happy with the raw response format, you may not need this. But if you want a cleaner interface that normalizes the messy NPPES response into a predictable structure, this saves you from writing that parsing layer yourself.

Getting started

  1. Look up by NPI: GET /lookup?number=1629067153
  2. Search by name: GET /search?last_name=Smith&state=TX
  3. Search by specialty: GET /search?taxonomy_description=Cardiology&state=CA
  4. MCP server: npx @easysolutions906/mcp-healthcare

No API key required. The API queries the live NPPES registry in real-time.

Top comments (0)