Joined answers
Everything about an NDC or an NPI in one call: RxNorm, J-codes, NADAC, label, shortage and recall flags for a drug; taxonomy, location, Medicare enrollment, opt-out and OIG exclusions for a provider.
Two routes answer "what do we know about this?" in one request:
GET /v1/drugs/ndc/{ndc}/full for a drug and GET /v1/providers/{npi}/full for a
provider. Both are part of the Pro and Team plans (403 plan-upgrade-required on Free and
Builder) and count as one lookup, however many datasets they join. The MCP tools are
get_drug_full and get_provider_full; the SDK methods are hdev.drugs.full() and
hdev.providers.full().
Drugs
Pass a product NDC (0006-3026), a package NDC in any 10-digit layout (0006-3026-02) or an
11-digit NDC (00006302602). The datasets are looked up together:
| Component | What it holds | Dataset |
|---|---|---|
product | The FDA product with its packages | NDC Directory |
rxnorm | RxNorm concepts linked to the product's (or the package's) NDC-11s | RxNorm |
asp | J-codes the current NDC-HCPCS crosswalk assigns, each with the payment limit in effect today and the newest quarter | Medicare Part B ASP |
nadac | The current NADAC rate of the package, or of each package of a product | NADAC (CMS) |
label | FDA label status: set id, version, effective date and which sections exist (not their text) | FDA drug labels |
shortage | Whether FDA lists a current shortage, with the shortage list entries | FDA drug shortages |
recalls | Whether FDA has a recall of the NDC it hasn't terminated, with the open recalls and closed ones from the last recall_months months (default 12) | FDA drug recalls |
Package or product
With a package NDC, every source that names packages is matched at the package level: RxNorm
links, crosswalk entries, NADAC rates, shortage entries (each is one presentation) and recalls
(the NDCs a recall names). A shortage entry or recall that names no package matches by product,
says matched_on: "product", and the component's reason notes it. product is always the
whole NDC Directory product, as /v1/drugs/ndc/{ndc} returns it.
hcpcs_codes lists the J-codes the newest or current quarter's crosswalk assigns. Codes only an
earlier quarter assigned are in asp.data.historical, with the last quarter that listed them.
open_recall is true for any recall of the NDC FDA hasn't terminated, however old;
recall_months only limits which closed recalls are listed next to the open ones.
Nothing is left out silently
Every component is always in the response, with a status:
available: the dataset was consulted anddataholds its answer. For the shortage and recall flags,falseis an answer: the dataset was checked and lists nothing.not_listed: the dataset was consulted and has nothing for this NDC.dataisnullandreasonsays what that means (for example, most retail pharmacy drugs have no J-code).unavailable: the dataset isn't published yet, or its license keeps it private.dataandsourcearenullandreasonsays which.
missing lists every component that isn't available, with its reason, so even the compact view
says why something has no answer. The flags (active_shortage, open_recall,
boxed_warning) are null, never false, when the data to answer isn't available.
Provenance per component
Each component carries its own source: the dataset, data_version, as_of (the date that
version takes effect), when it was published, the source URL, hashes and license terms. The
top-level meta combines every dataset consulted, the NDC Directory first, with each one's
provenance in meta.sources (see Responses).
Views
view=compact returns the flags and key ids only: ndc, product_ndc, ndc11, name,
rxcuis, hcpcs_codes, label_set_ids, flags and missing. standard and full (the
default) return every component. The MCP tool defaults to compact.
curl "https://api.healthcare.dev/v1/drugs/ndc/0006-3026-02/full?view=compact" \
-H "Authorization: Bearer $HDEV_API_KEY"{
"data": {
"ndc": "00006302602",
"product_ndc": "0006-3026",
"ndc11": "00006302602",
"name": "Keytruda (pembrolizumab)",
"rxcuis": [],
"hcpcs_codes": ["J9271"],
"label_set_ids": [],
"flags": { "active_shortage": false, "open_recall": false, "boxed_warning": null },
"missing": [
{
"component": "rxnorm",
"status": "not_listed",
"reason": "RxNorm links no concept to this package."
},
{
"component": "nadac",
"status": "not_listed",
"reason": "CMS publishes no current NADAC rate for this package (NADAC covers drugs retail pharmacies dispense; physician-administered and new products often have none)."
},
{
"component": "label",
"status": "not_listed",
"reason": "No current human prescription label on DailyMed lists this product (OTC, animal and withdrawn labels are not served)."
}
]
},
"meta": {
"source": "fda-ndc+nlm-rxnorm+cms-asp+cms-nadac+nlm-dailymed+openfda-drug-shortages+openfda-drug-enforcement",
"data_version": "ndc@2026-10-23,rxnorm@2026-10-05,medicare-asp@2026-10-r20261008,...",
"sources": ["..."]
}
}The example is illustrative and shortened. A payment limit is not a coverage decision or a patient price, NADAC is an average pharmacy acquisition cost, and no recall or shortage listed means FDA lists none, not that a product is safe. Reference data, not clinical or billing advice.
Providers
GET /v1/providers/{npi}/full takes a 10-digit NPI and looks up:
| Component | What it holds | Dataset |
|---|---|---|
provider | Who the NPI is: name, individual or organization, active or deactivated, enumeration and deactivation dates | NPI |
taxonomy | Every taxonomy listed for the NPI, the primary one, and NUCC's names when that code set is served | NPI |
location | The practice location address | NPI |
enrollment | enrolled and the Medicare fee-for-service enrollments that list the NPI | Medicare enrollment |
opt_out | opted_out today and the affidavit in effect, else the latest listed (in_effect says which) | Medicare opt-out |
exclusion | exclusion_recorded, matched_by: "npi_as_listed" and the exclusion records, in effect or reinstated | OIG exclusions |
The checks answer exactly as /v1/providers/{npi}/enrollment, /opt-out and /exclusions do,
with the same note. Provider data comes from the CMS NPI Registry until the NPPES file is
published (the provider source says which). An NPI the provider source has no record of is a
404 with a hint.
Not listed is not "no"
A check whose current file doesn't list the NPI (no records, or only ones a later release dropped) is not_listed, and its reason is the check's own
note. Above all for exclusions: exclusions are matched by NPI as listed in the OIG file, and
most OIG records carry no NPI, so exclusion_recorded: false means no exclusion recorded with
this NPI, never that the provider is not excluded. Search by name too (/v1/exclusions?q=) and
confirm identity with OIG's online search. exclusion_note carries that rule in words, in every
view; show it with the answer.
A dataset that isn't published, or whose license keeps it private, is unavailable: its flag is
null, never false. flags are medicare_enrolled, opted_out and exclusion_recorded;
missing lists every component that isn't available, with its reason.
Views and provenance
view=compact returns npi, name, entity_type, status, primary_taxonomy,
practice_location, flags, exclusion_note and missing. Each component has its own
source with data_version and as_of, and meta combines the provider source, NUCC (when it
named taxonomies) and each check dataset consulted.
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",
"primary_taxonomy": { "code": "1223G0001X", "name": null },
"practice_location": { "city": "BRISTOL", "state": "VA", "postal_code": "242024317" },
"flags": { "medicare_enrolled": false, "opted_out": true, "exclusion_recorded": true },
"exclusion_note": "Matched by NPI as listed in the OIG file (LEIE). Most LEIE records carry no NPI, so an empty answer means no exclusion recorded with this NPI, not that the provider is not excluded: ...",
"missing": [
{
"component": "enrollment",
"status": "not_listed",
"reason": "Matched by NPI (the enrollment's NPI or one of its additional NPIs) in CMS's Medicare Fee-For-Service Public Provider Enrollment file, release 2026-10-01. Not listed means that file has no enrollment with this NPI, not a determination of eligibility."
}
]
},
"meta": {
"data_version": "nppes@2026-10,medicare-enrollment@2026-10-01,medicare-opt-out@2026-08-01,oig-exclusions@2026-10-09",
"sources": ["..."]
}
}The example is illustrative and shortened. Reference data, not a credentialing decision: confirm an exclusion's identity with OIG before acting on it.
Coverage change feed
Material changes to Medicare coverage documents as we detect them: what changed, the codes affected, the effective date and the page to check.
Webhooks
Get dataset releases, changes to the codes, NDCs and NPIs you care about, and Medicare coverage changes pushed to your endpoint, signed.