Verify a provider
Before you schedule, refer or pay: does the NPI exist, is it active, is it enrolled in Medicare, has it opted out, does OIG list an exclusion, and do the sources disagree.
| Plan | Free for each check. Pro for the one-call answer with source conflicts and possible exclusion matches (Joined answers) |
| Datasets | NPI, Medicare enrollment, Medicare opt-out, OIG exclusions |
| Calls per answer | 4 on Free (validate, enrollment, opt-out, exclusions), 1 on Pro |
Free: four checks
NPI=1003926940
for check in validate enrollment opt-out exclusions; do
curl -s "https://api.healthcare.dev/v1/providers/$NPI/$check" \
-H "Authorization: Bearer $HDEV_API_KEY" | jq -c '.data | del(.enrollments, .affidavits, .exclusions)'
done{"npi":"1003926940","valid_format":true,"valid_check_digit":true,"exists":true,"status":"active","deactivation_history":[]}
{"npi":"1003926940","enrolled":false,"note":"Matched by NPI (the enrollment's NPI or one of its additional NPIs) in CMS's Medicare Fee-For-Service Public Provider Enrollment file, ..."}
{"npi":"1003926940","opted_out":true,"note":"..."}
{"npi":"1003926940","exclusion_recorded":true,"matched_by":"npi_as_listed","note":"Matched by NPI as listed in the OIG file (LEIE). Most LEIE records carry no NPI, ..."}TypeScript
import { HealthcareDev } from "@healthcare.dev/sdk";
const hdev = new HealthcareDev(); // reads HDEV_API_KEY
const npi = "1003926940";
const [id, enrollment, optOut, exclusions] = await Promise.all([
hdev.providers.validate(npi),
hdev.providers.enrollment(npi),
hdev.providers.optOut(npi),
hdev.providers.exclusions(npi),
]);
console.log({
exists: id.data.exists,
status: id.data.status, // "active" | "deactivated" | null
medicare_enrolled: enrollment.data.enrolled,
opted_out: optOut.data.opted_out,
exclusion_recorded: exclusions.data.exclusion_recorded,
exclusion_note: exclusions.data.note, // show this with the answer
});Python
from healthcare_dev import HealthcareDev
hdev = HealthcareDev() # reads HDEV_API_KEY
npi = "1003926940"
checks = {
"id": hdev.providers.validate(npi)["data"],
"enrollment": hdev.providers.enrollment(npi)["data"],
"opt_out": hdev.providers.opt_out(npi)["data"],
"exclusions": hdev.providers.exclusions(npi)["data"],
}
print(checks["id"]["exists"], checks["id"]["status"])
print(checks["enrollment"]["enrolled"], checks["opt_out"]["opted_out"])
print(checks["exclusions"]["exclusion_recorded"], checks["exclusions"]["note"])Also search exclusions by name
Most OIG exclusion records carry no NPI, so exclusion_recorded: false means "no exclusion
recorded with this NPI", never "not excluded". Search by name and state as well:
curl "https://api.healthcare.dev/v1/exclusions?q=shelburne&state=VA" \
-H "Authorization: Bearer $HDEV_API_KEY"const byName = await hdev.exclusions.search({ q: "shelburne", state: "VA" });by_name = hdev.exclusions.search(q="shelburne", state="VA")A name match is not an identity match: confirm with OIG's online search, which checks SSN or EIN.
Pro: one call, with conflicts
GET /v1/providers/{npi}/full runs every check above in one billed call and adds what the
separate checks can't: where NPPES and Medicare enrollment (PECOS) disagree, and OIG records
without an NPI that may be this provider.
curl "https://api.healthcare.dev/v1/providers/1003926940/full?view=compact" \
-H "Authorization: Bearer $HDEV_API_KEY"{
"data": {
"npi": "1003926940",
"name": "ROY S SHELBURNE, DDS",
"entity_type": "individual",
"status": "active",
"flags": { "medicare_enrolled": false, "opted_out": true, "exclusion_recorded": true },
"exclusion_note": "Matched by NPI as listed in the OIG file (LEIE). ...",
"missing": [{ "component": "enrollment", "status": "not_listed", "reason": "..." }],
"conflicts": [],
"conflicts_checked": []
},
"meta": { "data_version": "nppes@2026-10,medicare-enrollment@2026-10-01,...", "sources": ["..."] }
}const { data } = await hdev.providers.full("1003926940", { view: "compact" });
console.log(data.flags, data.exclusion_note, data.conflicts);full = hdev.providers.full("1003926940", view="compact")["data"]
print(full["flags"], full["exclusion_note"], full["conflicts"])Ask an agent
With the MCP server connected:
Verify NPI 1003926940 before I schedule with them: is the NPI active, are they enrolled in Medicare or opted out, and does the OIG list an exclusion? Show each answer's note and cite the source and data version.
The agent uses validate_npi, check_medicare_enrollment, check_medicare_opt_out and
check_provider_exclusion, or get_provider_full on Pro.
Read the answer
not_listedis not "no". A check whose file doesn't list the NPI says so in itsnote. Show the note next to the answer.- A flag of
null(Pro) means the dataset to answer isn't available, neverfalse. - Conflicts are shown, never settled.
conflictslists the fact with every source's value,as_ofand page; we don't pick a winner. An emptyconflictsmeans the facts inconflicts_checkedagree; a fact not inconflicts_checkedwasn't compared. - Possible exclusion matches (
exclusion_matches, Pro) are OIG records without an NPI with the same name in the same state, scored on middle name, address and specialty. Each says how it was reached:derivation: "derived"means fixed matching rules published it on their own (one candidate, strong evidence);"reviewed"means a person checked it first.confidence(0 to 1) is how strong the evidence is. A possible match is never a finding that the provider is excluded.
What it is not
Reference data, not a credentialing or enrollment determination. Confirm an exclusion's identity with OIG's online search before acting on it, and check enrollment with your Medicare Administrative Contractor when it matters for payment.
All recipes
One page per job: which endpoints to call, in what order, on which plan, with curl, TypeScript, Python and an MCP prompt.
Check Medicare coverage for a code and diagnosis
Does a Medicare local coverage document list this diagnosis as supporting this procedure code in this state? With how the answer was reached and the CMS page to check.