nppes_lookup_provider
Look up US healthcare providers in the CMS NPPES registry. Validate NPIs and retrieve taxonomy, addresses, and practice locations for subcontractor due diligence.
Instructions
Keyless CMS/HHS NPPES NPI Registry lookup — the authoritative PUBLIC registry of every US healthcare provider (individual NPI-1 + organization NPI-2), for VA/HHS/CMS subcontractor/provider/teaming due-diligence (validate an NPI, confirm taxonomy/specialty, enumeration status, practice state, org/name match). Host npiregistry.cms.hhs.gov/api (version=2.1). Mode is inferred from number (no mode flag). EXACT-NPI mode (number given): the NPI is CMS-Luhn-validated client-side (Luhn over 80840+first-9) ⇒ a typo'd NPI is invalid_input, NEVER a fake 'does not exist'; ★the wire query carries number (+version) ALONE — any co-supplied filter (last_name/state/…) is DROPPED from the wire and checked CLIENT-SIDE (disclosed in data.filterMatch:{field:bool} + data.filtersDropped), because NPPES AND-combines a number with filters and a mismatch would falsely zero a real active provider into found:false. SEARCH mode: required-one of { first_name, last_name, organization_name, taxonomy_description, city, postal_code } (state + enumeration_type are REFINERS ONLY — rejected alone); a trailing '*' wildcard on a name/org field needs ≥2 leading literal chars. Returns EXACT-mode { found, provider:{ number, enumerationType, active, status, basic{…individual OR org fields, null-never-fabricated…}, taxonomies[{code,desc,primary,state,license,taxonomyGroup}], addresses[{purpose,address1,city,state,postalCode,telephone,fax,countryCode}], practiceLocations[…same, SEPARATE from addresses], identifiers[], otherNames[], endpoints[], createdEpoch, lastUpdatedEpoch }, filterMatch? } OR SEARCH-mode { providers:[…] } + honest _meta. HONESTY: active = basic.status==='A' (a deactivated/absent NPI is NOT active); epochs are ms numeric STRINGS → number|null (null-never-0); addresses[] and practiceLocations[] are kept SEPARATE (a provider can practice in a state that appears ONLY in practiceLocations); NPPES exposes NO match total, so a full page ⇒ totalAvailable is a disclosed LOWER BOUND (totalIsLowerBound) + a ~1,200-row-per-query reach cap (limit ≤ 200, skip ≤ 1,000 — OUR policy, a PER-QUERY cap only; cross-query enumeration is not architecturally prevented). A genuine {result_count:0} ⇒ honest found:false/empty; a {Errors:[…]} 200 body (no results key) ⇒ THROWS invalid_input (never a fake empty); any 4xx/5xx/timeout/off-host-redirect ⇒ THROWS; result_count !== results.length ⇒ schema_drift. ★NOT a fitness/exclusion/licensure/sanctions determination — cross-check SAM exclusions + OFAC; individual (NPI-1) records may surface personal/home addresses + phone/fax verbatim with NO enrichment. The caveat + reach-cap disclosure ride EVERY response.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| city | No | Address city (a required-one criterion). e.g. 'Baltimore'. | |
| skip | No | 0-based pagination offset, 0..1000 (default 0). ★POLICY cap: this vetting tool reaches at most the first ~1,200 matches/query (a deliberate targeted-lookup boundary — NPPES itself no longer enforces a skip ceiling); skip > 1000 ⇒ invalid_input. Search mode only. | |
| limit | No | Providers per page, 1..200, default 10. NPPES silently clamps >200; this tool rejects it loudly. Search mode only. | |
| state | No | US state/territory 2-letter USPS code — a REFINER only (never sufficient alone ⇒ invalid_input; NPPES rejects 'state' as the sole criterion). e.g. 'MD'. | |
| number | No | Exact NPI — 10 digits (^\d{10}$). Triggers EXACT-NPI mode: the wire query carries number (+version) ALONE (any co-supplied filter is DROPPED from the wire and checked client-side, disclosed in data.filterMatch — NPPES AND-combines a number with filters, so a mismatched filter would falsely zero a real active provider). Also client-side CMS-Luhn-validated (Luhn over 80840+first-9): a typo'd NPI ⇒ invalid_input, NEVER a fake 'does not exist'. e.g. '1104130236'. | |
| last_name | No | Individual provider last name (a required-one criterion). Trailing '*' wildcard: ≥2 leading chars. e.g. 'Smith'. | |
| first_name | No | Individual provider first name (a required-one criterion). A trailing '*' wildcard needs ≥2 leading literal chars. e.g. 'John'. | |
| postal_code | No | Address postal/ZIP code (a required-one criterion; a prefix like '212' is allowed). e.g. '21218'. | |
| enumeration_type | No | REFINER only (NPI-1 = individual, NPI-2 = organization). Never sufficient alone (⇒ invalid_input) — must accompany a required criterion. | |
| organization_name | No | Organization (NPI-2) name (a required-one criterion). Trailing '*' wildcard: ≥2 leading chars. e.g. 'Mayo Clinic'. | |
| taxonomy_description | No | Provider taxonomy/specialty description (a required-one criterion). e.g. 'Internal Medicine'. |