How to look up an NPI with the API
Send a GET request to /v1/providers/{npi} with your API key.
You get back the provider's NPPES record as JSON: name or organization name, status,
primary taxonomy, practice address and the dates that matter. Call it from your server, not
from browser code, so your key stays private.
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.npilayer.com/v1/providers/1234567893"
async function lookupNpi(npi) {
const res = await fetch(`https://api.npilayer.com/v1/providers/${npi}`, {
headers: { Authorization: 'Bearer YOUR_API_KEY' },
});
const body = await res.json();
if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message}`);
return body.data;
}
import requests
def lookup_npi(npi):
res = requests.get(
f"https://api.npilayer.com/v1/providers/{npi}",
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=10,
)
body = res.json()
if not res.ok:
raise ValueError(f"{body['error']['code']}: {body['error']['message']}")
return body["data"]
Every endpoint takes the same header. See authentication for the details, and the provider endpoint reference for PHP examples and every parameter.
What the NPI API returns
The lookup response has a data object and a meta object whose
source is always CMS NPPES. These are the fields in
data:
| Field | Type | What it holds |
|---|---|---|
npi | string | The 10-digit NPI |
entity_type | string | individual (Type 1) or organization (Type 2) |
name | object or null | For individuals: first, middle, last and credential. Null for organizations |
organization_name | string or null | The organization's name. Null for individuals |
status | string | active or deactivated |
enumeration_date | date | When the NPI was assigned |
last_updated | date | When the NPPES record last changed |
deactivation_date | date or null | Set when the NPI has been deactivated |
primary_taxonomy | object or null | The provider's primary taxonomy code and its description |
practice_address | object or null | Primary practice location: address_1, address_2, city, state, postal_code, country |
The source data has more than 300 columns, with taxonomy and address fields that repeat
many times. We turn that into one consistent shape, so your code reads
data.primary_taxonomy.code and not column 48 of a CSV.
Validate an NPI before you look it up
An NPI's last digit is a check digit, so a mistyped number can be caught without a database lookup. The API does that check for you and tells you exactly what went wrong, using four different outcomes instead of one generic error:
| What you sent | HTTP status | Response |
|---|---|---|
| Not exactly 10 digits | 400 | invalid_npi_format |
| 10 digits, but the check digit fails | 422 | invalid_npi_checksum |
| Well formed, but not in NPPES | 404 | provider_not_found |
| Found | 200 | The record, with status set to active or deactivated |
For example, 1234567890 is ten digits but fails the check:
{ "error": { "code": "invalid_npi_checksum", "message": "This NPI fails the standard NPI check-digit validation and cannot be a real, assigned NPI." } }
Passing the check digit does not mean an NPI has been assigned, which is why there is a
separate 404. 1234567893 passes the check but is not a
real provider, so it returns:
{ "error": { "code": "provider_not_found", "message": "No provider was found for the supplied NPI." } }
Want the check-digit method itself? It is explained step by step in what an NPI is and how the check digit works.
NPI API endpoints
| Endpoint | Use it to |
|---|---|
GET /v1/providers/{npi} | Look up one provider or organization by NPI. Docs |
GET /v1/providers/search | Search by name, organization, city, state, ZIP, specialty or taxonomy code. Docs |
GET /v1/providers/nearby | Find providers within a radius of a ZIP code, nearest first. Docs |
GET /v1/taxonomies | List the taxonomy (specialty) codes. Docs |
GET /v1/taxonomies/search | Search taxonomy codes by keyword or code. Docs |
Search providers by name, specialty and location
Search filters combine. Use name, first_name, last_name or
organization, narrow by city, state or zip,
and filter by specialty (a text match) or taxonomy (an exact code).
Results are paged: 25 per page by default and up to 100.
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.npilayer.com/v1/providers/search?last_name=smith&state=MI"
{ "data": [ { "npi": "1234567893", "entity_type": "individual", "name": "Jane Smith, MD", "specialty": "Cardiovascular Disease Physician", "city": "Traverse City", "state": "MI", "status": "active" } ], "meta": { "count": 1, "has_more": false, "page": 1, "limit": 25 } }
The nearby endpoint adds a radius and returns each provider's
distance_miles, nearest first:
curl -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.npilayer.com/v1/providers/nearby?zip=49684&taxonomy=207RC0000X&radius=25"
{ "data": [ { "npi": "1234567893", "entity_type": "individual", "name": "Jane Smith, MD", "specialty": "Cardiovascular Disease Physician", "city": "Traverse City", "state": "MI", "status": "active", "distance_miles": 3.8 }, { "npi": "1234567901", "entity_type": "individual", "name": "Robert Lee, DO", "specialty": "Cardiovascular Disease Physician", "city": "Traverse City", "state": "MI", "status": "active", "distance_miles": 7.2 } ], "meta": { "count": 2, "page": 1, "limit": 25, "radius_miles": 25, "center": { "zip": "49684" } } }
Three things to know about how matching works:
- Distances are approximate. They are measured from the center of the ZIP code, not from a street address.
- Filters match the primary taxonomy only. A provider who lists a specialty only as a secondary code does not match it, as explained here.
-
Use the taxonomy code for exact results. The
specialtyfilter is a plain text match against NUCC's names, and NUCC calls general cardiology “Cardiovascular Disease”. A search forspecialty=cardiologytherefore finds only the subspecialties with that word in their name. The exact code207RC0000Xfinds them all. Look up the code for any specialty.
Where the data comes from
NPILayer is built on the National Plan and Provider Enumeration System (NPPES), which CMS publishes as a full file each month and incremental updates each week. We import both into our own database. Your requests are answered from that copy, not from a live call to CMS, so lookups do not depend on anyone else's uptime.
The data is current as of September 13, 2026. Deactivated NPIs stay in the data with status set to deactivated, so
you can flag them instead of failing to find them.
Provider information is based on publicly available NPPES data. An NPI does not indicate licensure, credentialing, network participation, or current practice status. The API is not a credentialing or primary-source verification service.
NPI API pricing
Plans are priced by request volume, and there are no per-record fees. Each plan has a monthly request quota, shared by all the keys on your account, and a per-minute burst limit that protects the service from runaway scripts.
| Plan | Price | Requests per month | Requests per minute |
|---|---|---|---|
| Free | Free | 1,000 | 30 |
| Developer | $29 per month, or $290 per year | 25,000 | 60 |
| Pro | $149 per month, or $1,490 per year | 250,000 | 300 |
| Scale | $499 per month, or $4,990 per year | 1,000,000 | 1,000 |
If you go over your monthly quota, the API returns a 429 with the code
monthly_quota_exceeded and the time it resets. Going over the per-minute limit
returns a 429 with burst_rate_limit_exceeded and a
Retry-After header. See rate limits for the
details, or the full pricing page.
Frequently asked questions
Is there a free NPI API?
Yes. The free plan includes 1,000 requests a month and all five endpoints. You need an account and an API key, but not a credit card.
How do I authenticate?
Send your key as Authorization: Bearer YOUR_API_KEY. You can create and revoke
keys from your dashboard, and a key is shown only once when you create it.
Does the API check that an NPI is valid?
It checks the format and the check digit, then looks the number up in NPPES. Each outcome has its own status and error code, as shown above. A number can pass the check digit and still not be assigned to anyone.
How current is the data?
We import CMS's weekly updates and monthly full file. Records can still lag what a provider has told CMS, because providers maintain their own NPPES information.
Can I use it to verify a provider's license or credentials?
No. An NPI shows that a provider or organization was enumerated by CMS. It does not show licensure, credentialing, network participation or whether they currently practice at an address. Verify those with the licensing board, the health plan or the provider.
Can I just use the free NPI lookup tool instead?
For looking up a provider by hand, yes: the free NPI lookup and provider search need no account. For anything automated, use the API. Our terms do not allow scraping the web tools.
Related
- Healthcare Provider API: the broader overview of provider data, search and geographic lookup
- What is an NPI number?: format, types and the check digit
- NPI taxonomy codes: search and browse the specialty code set
- API documentation: authentication, errors, rate limits and every endpoint