Providers
Three endpoints cover the core provider use cases: looking up a known NPI, searching by name or specialty, and finding providers near a location.
NPI lookup
Retrieve a single provider by NPI number. This is the fastest and most precise query.
Path parameters
| Parameter | Type | Description |
|---|---|---|
| npi required | string | 10-digit NPI number. The API validates format and check digit before querying the database. |
Response
| Field | Type | Description |
|---|---|---|
| npi | string | The NPI number. |
| entity_type | string | individual or organization. |
| name | object|null | Name fields for individuals (first, middle, last, credential). Null for organizations. |
| organization_name | string|null | Organization name. Null for individuals. |
| status | string | active or deactivated. |
| enumeration_date | string | Date the NPI was assigned (ISO 8601). |
| last_updated | string | Date the NPPES record was last updated (ISO 8601). |
| deactivation_date | string|null | Date deactivated, if applicable. |
| primary_taxonomy | object|null | Primary taxonomy code and description (code, description). |
| practice_address | object|null | Primary practice location (address_1, address_2, city, state, postal_code, country). |
curl \ -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.npilayer.com/v1/providers/1003000126"
$ch = curl_init('https://api.npilayer.com/v1/providers/1003000126');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NPILAYER_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
$provider = $body['data'];
const r = await fetch('https://api.npilayer.com/v1/providers/1003000126', {
headers: { 'Authorization': `Bearer ${process.env.NPILAYER_API_KEY}` }
});
const { data: provider } = await r.json();
import os, requests
r = requests.get(
'https://api.npilayer.com/v1/providers/1003000126',
headers={'Authorization': f"Bearer {os.environ['NPILAYER_API_KEY']}"}
)
provider = r.json()['data']
{
"data": {
"npi": "1003000126",
"entity_type": "individual",
"name": {
"first": "Jane",
"middle": "A",
"last": "Smith",
"credential": "MD"
},
"organization_name": null,
"status": "active",
"enumeration_date": "2008-04-14",
"last_updated": "2026-08-21",
"deactivation_date": null,
"primary_taxonomy": {
"code": "207RC0000X",
"description": "Cardiovascular Disease Physician"
},
"practice_address": {
"address_1": "123 Main St",
"address_2": null,
"city": "Traverse City",
"state": "MI",
"postal_code": "49684",
"country": "US"
}
},
"meta": {
"source": "CMS NPPES"
}
}
Provider search
Search for providers using name, location, specialty, and other filters. At least one filter parameter is recommended — an empty query returns paginated results across all providers.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| name | string | Partial match against first name, last name, or organization name. |
| first_name | string | Filter by first name (individuals only). |
| last_name | string | Filter by last name (individuals only). |
| organization | string | Filter by organization name. |
| entity_type | string | individual or organization. |
| city | string | Filter by practice city. |
| state | string | Two-letter state abbreviation (e.g. MI). |
| zip | string | 5-digit ZIP code of the practice address. |
| taxonomy | string | Exact NUCC taxonomy code (e.g. 207RC0000X). |
| specialty | string | Partial text match against the NUCC taxonomy names (display name, classification, specialization). NUCC's wording differs from everyday terms, so common ones are also searched by NUCC's wording: cardiology also finds Cardiovascular Disease, and orthopedic also finds Orthopaedic. Use taxonomy for an exact code. |
| limit | integer | Results per page. Default 25, maximum 100. |
| page | integer | Page number, 1-based. Default 1. |
curl \ -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.npilayer.com/v1/providers/search?last_name=smith&state=MI&taxonomy=207RC0000X"
$params = http_build_query([
'last_name' => 'smith',
'state' => 'MI',
'taxonomy' => '207RC0000X',
]);
$ch = curl_init('https://api.npilayer.com/v1/providers/search?' . $params);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NPILAYER_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
const params = new URLSearchParams({
last_name: 'smith',
state: 'MI',
taxonomy: '207RC0000X',
});
const r = await fetch(
`https://api.npilayer.com/v1/providers/search?${params}`,
{ headers: { 'Authorization': `Bearer ${process.env.NPILAYER_API_KEY}` } }
);
const { data, meta } = await r.json();
import os, requests
r = requests.get(
'https://api.npilayer.com/v1/providers/search',
params={'last_name': 'smith', 'state': 'MI', 'taxonomy': '207RC0000X'},
headers={'Authorization': f"Bearer {os.environ['NPILAYER_API_KEY']}"}
)
body = r.json()
providers = body['data']
meta = body['meta']
{
"data": [
{
"npi": "1003000126",
"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
}
}
Paging
meta.count is the number of results on this page, not the total.
meta.has_more is true when another page exists: request the next one with
page=2, and so on. Search does not report a total, because counting every match across
millions of records would make each request slow.
Geographic search
Find providers within a radius of a ZIP code or GPS coordinates. Results are ordered by distance ascending and include a distance_miles field. Location resolution is ZIP-centroid based — distances are approximate.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| zip required* | string | 5-digit ZIP code to search around. Required unless lat/lng are provided. |
| lat required* | number | Latitude in decimal degrees. Provide with lng as an alternative to zip. |
| lng required* | number | Longitude in decimal degrees. Provide with lat as an alternative to zip. |
| radius | number | Search radius in miles. Default 25. |
| taxonomy | string | Exact NUCC taxonomy code. |
| specialty | string | Partial text match against taxonomy display name. |
| limit | integer | Results per page. Default 25, maximum 100. |
| page | integer | Page number, 1-based. Default 1. |
* Provide either zip or both lat and lng. Providing none returns a 400 invalid_location error.
# By ZIP code curl \ -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.npilayer.com/v1/providers/nearby?zip=49684&taxonomy=207RC0000X&radius=25" # By coordinates curl \ -H "Authorization: Bearer YOUR_API_KEY" \ "https://api.npilayer.com/v1/providers/nearby?lat=44.7631&lng=-85.6206&radius=50"
$params = http_build_query([
'zip' => '49684',
'taxonomy' => '207RC0000X',
'radius' => 25,
]);
$ch = curl_init('https://api.npilayer.com/v1/providers/nearby?' . $params);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('NPILAYER_API_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
const params = new URLSearchParams({
zip: '49684',
taxonomy: '207RC0000X',
radius: '25',
});
const r = await fetch(
`https://api.npilayer.com/v1/providers/nearby?${params}`,
{ headers: { 'Authorization': `Bearer ${process.env.NPILAYER_API_KEY}` } }
);
const { data, meta } = await r.json();
import os, requests
r = requests.get(
'https://api.npilayer.com/v1/providers/nearby',
params={'zip': '49684', 'taxonomy': '207RC0000X', 'radius': 25},
headers={'Authorization': f"Bearer {os.environ['NPILAYER_API_KEY']}"}
)
body = r.json()
providers = body['data']
{
"data": [
{
"npi": "1003000126",
"entity_type": "individual",
"name": "Jane Smith, MD",
"specialty": "Cardiovascular Disease Physician",
"city": "Traverse City",
"state": "MI",
"status": "active",
"distance_miles": 3.8
}
],
"meta": {
"count": 1,
"page": 1,
"limit": 25,
"radius_miles": 25,
"center": {
"zip": "49684"
}
}
}
Paging
Here meta.count is the total number of providers within the radius, not
the number on this page. Use limit and page to walk through them. This differs
from provider search, where meta.count is the number on the current page.
meta.center is {"zip": "..."} for a ZIP code search and
{"lat": ..., "lng": ...} for a coordinate search.