Methodology · September 2026

How to map drugs to indications — and why open data gets it wrong

Knowing why a drug was prescribed is the question underneath formulary modeling, market sizing and diagnosis suspecting. Open data can't answer it. We built our own indication ontology to model it the way a clinician thinks — and only then mapped it to the codes you already use.

Short answer

To map drugs to diseases, you need three things open sources don't provide together: a weight for each indication (the share of prescriptions written for it), the condition the patient has rather than the symptom the drug acts on, and off-label use. TwinFyRx models each use as its own indication concept, estimates shares per RxNorm drug, validates them against AHRQ MEPS, and maps them to billable ICD-10-CM codes.

5,882

indication concepts

11,486

RxNorm drugs mapped

544

clinical conditions

21

body systems

The short version: why open data can't say why a drug was prescribed, and how we map it instead.

Why can't you map drugs to diseases with open data?

Our first attempt was the obvious one. The National Library of Medicine publishes drug–disease relationships through MED-RT, exposed in RxClass and RxNav. It's free, it's keyed to RxNorm, and it's maintained by people who know what they're doing. We wired it up, pointed it at real prescriptions, and the answers were wrong in ways no amount of cleanup could fix.

That's not a knock on NLM. MED-RT answers a different question — what is this drug known to treat? — and answers it as a flat list. Analytics needs what does the patient behind this fill have, and how often? Three gaps separate the two:

  • Coded to the target, not the patient. A muscle relaxant maps to muscle spasm. The claim that goes with the fill says low back pain.
  • No weights. Every relationship counts the same. A use that drives a third of volume and one that drives a rounding error look identical.
  • Label-bound. Off-label use — often most of a drug's volume — is largely absent.

Cyclobenzaprine: the drug treats spasm. The claim says back pain.

MED-RT lists seven conditions cyclobenzaprine may treat:

Muscle crampMuscle rigidityMuscle spasticityMyositisPainSpasmTetanus

Every one describes what the drug acts on — or, in tetanus, a use almost no outpatient prescription is for. None is the diagnosis a payer sees next to the fill. Weighted equally, tetanus gets the same 14% as everything else. Here is how we map the 10 mg tablet, with the billable code each use lands on:

UsePatient hasICD-10-CMShare of fills
Muscle spasm in acute low back painacute low back painM54.50
35%
Muscle spasm in acute neck pain or cervical strainacute neck pain (cervical strain)S13.4XXA
15%
Muscle spasm in chronic low back painchronic low back painM54.50
12%
Muscle spasm in acute musculoskeletal sprain or strainacute sprain or strainT14.90XA
10%
Fibromyalgia with sleep disturbancefibromyalgiaM79.7
7%
Myofascial pain syndromemyofascial pain syndromeM79.18
6%
6 further usesosteoarthritis, TMJ disorder, tension headache …
15%

MED-RT relationships retrieved from the NLM RxClass API, September 2026.

The same pattern runs through every symptom-relief drug. For ondansetron, MED-RT lists two relationships — postoperative nausea and alcoholism. In practice a quarter of ondansetron is written for nausea with no recorded cause, a fifth for gastroenteritis, and meaningful shares for pregnancy, chemotherapy and migraine. In each case the claim carries the underlying condition, not the nausea. Where no cause is recorded, we say so rather than invent one: a suspecting model that assigns cancer to every antiemetic fill is worse than one that admits it doesn't know.

Gabapentin: why equally weighted indications are useless

Cyclobenzaprine shows the coding problem. Gabapentin shows the weighting problem. MED-RT lists four uses — postherpetic neuralgia, partial seizures, bipolar disorder and phobic disorders. Consume them as-is and each gets a quarter of the volume. In practice those four account for about 11% of gabapentin prescribing; the drug's real footprint is neuropathic and radicular pain, almost all of it off-label.

Use (gabapentin 300 mg capsule)MED-RT, equalTwinFyRx
Painful diabetic peripheral neuropathy—20%
Lumbar radiculopathy—14%
Peripheral neuropathic pain, mixed cause—12%
Chronic pain, opioid-sparing adjunct—8%
Postherpetic neuralgia25%5%
Partial-onset seizures (adjunctive)25%5%
Bipolar disorder (adjunctive)25%1%
Phobic disorders25%—
13 further uses (anxiety, fibromyalgia, restless legs, hot flashes …)—35%

Why build an indication ontology before mapping to ICD-10?

The tempting shortcut is to map drugs straight to ICD-10. ICD-10 is a billing classification: it forces every idea into whatever code a claim would carry, at whatever specificity the code set happens to offer. “Stroke prevention in atrial fibrillation” becomes an atrial fibrillation code and the prevention intent disappears. “Muscle spasm in acute low back pain” becomes either a spasm code or a back pain code — pick one, lose the other.

So the foundation is our own vocabulary — the TwinFyRx Indication — written the way a prescriber or pharmacist would say it, and coded at the level of detail the source actually supports. Each concept separates the parts a code collapses:

IndicationRelationshipPatient hasDrug acts on
Glycemic control in type 2 diabetesMetformintreatstype 2 diabeteshyperglycemia
Stroke prevention in nonvalvular atrial fibrillationApixabanpreventsatrial fibrillationstroke and systemic embolism
Muscle spasm in acute low back painCyclobenzaprinetreats a symptom ofacute low back painmuscle spasm
Nausea and vomiting of pregnancyOndansetrontreats a symptom ofpregnancynausea and vomiting

Patient has is the field that matters most: it is the diagnosis that would sit on the claim for that fill, which is what suspecting and claims matching need. Concepts can also carry a qualifier (first-line, adjunctive, palliative), up to three associated conditions, and a parent, so “painful diabetic neuropathy” and “postherpetic neuralgia” both roll up to “neuropathic pain, any cause.”

Keeping the ontology ours is what keeps us flexible. When ICD-10 revises a code, when a buyer wants SNOMED instead, or when we find two concepts that should be one, we change one mapping — not thousands of drug rows. The drug estimates never have to be redone because a code set moved.

How does it map to ICD-10, SNOMED CT and MeSH?

Nobody builds on our ontology — nor should they have to. Your claims speak ICD-10; your clinical systems speak SNOMED CT; your literature pipelines speak MeSH. So the last step translates every concept into a clinical condition layer built on AHRQ's Clinical Classifications Software Refined (CCSR), and from there into standard codes. Every ICD-10-CM code in our drug-level estimates is billable; where a source only supports a category, we roll it down to the unspecified child rather than publish a code a claim can't carry.

Drug

RxNorm SCD / SBD

→

TwinFyRx Indication

how clinicians describe the use

→

Condition

CCSR-based, 544 groups

→

Standard codes

ICD-10-CM · SNOMED CT · MeSH

The published grain is the drug: every RxNorm clinical and branded drug carries its indication shares (drug_indication), and drug_icd10_estimate rolls them to billable codes. You join on drug_id and never have to learn our vocabulary unless you want to.

How is the mapping built?

We won't publish the recipe, but the shape is simple: a multi-stage, AI-assisted research workflow with domain experts deciding what ships. Five stages, each auditable, each result kept as an immutable, versioned run rather than overwritten — and every release tested against real-world prescription data before it is published.

  1. 01

    Research

    Frontier AI models, run as a structured research workflow, work through each drug the way a clinical pharmacist would — drawing on FDA labeling, guidelines and the published real-world utilization literature — and record how it is actually used, on-label and off.

  2. 02

    Normalize

    Express every use as a TwinFyRx Indication. Reuse an existing concept before minting a new one, so ten drugs for the same job share one concept.

  3. 03

    Curate

    Review the vocabulary chapter by chapter: merge duplicates, build parent–child structure. Every change is logged and reversible.

  4. 04

    Estimate

    Weight each drug's uses by share of prescriptions — per drug form, or per product line where one form serves different markets.

  5. 05

    Translate

    Code each concept's conditions once — to a clinical condition group and billable ICD-10-CM — then publish at the drug (RxNorm SCD/SBD) grain.

Two design choices matter more than the rest. First, estimation happens at the level where use actually differs — usually the drug form, but per product line where one form serves different markets. Finasteride 1 mg is a hair-loss drug (91% male pattern hair loss); the 5 mg tablet is a prostate drug (77% BPH). Mounjaro and Zepbound are the same tirzepatide pen — one is 87% type 2 diabetes, the other 70% obesity. Second, the vocabulary is shared across the whole catalog, so a new drug inherits concepts its therapeutic neighbors already use instead of inventing near-duplicates.

How is it validated?

Indication shares are an estimate, and we treat them like one. Nothing publishes until it clears four gates:

External benchmark: AHRQ MEPS

The Medical Expenditure Panel Survey links each prescription fill to the condition the household reported it was for. We score how much of each drug's volume lands on the same condition group MEPS sees.

Clinical review before publish

A random sample of everything that would ship — drug mappings, condition coding, vocabulary merges, new parent concepts — reviewed by hand. We publish only if the sample passes.

Known-error audit

A gold set of confirmed mapping mistakes, re-checked on every run so old errors can't quietly return.

Structural checks

Shares sum to 100% per drug, every drug-level ICD-10 code is billable, no orphaned or merged concepts, and every vocabulary change carries an audit record.

0.65

median volume overlap with MEPS-reported conditions

MEPS agrees with itself across survey periods at 0.81

73%

of drug forms: our top condition is MEPS's top condition

513 drug forms with ≥ 100 MEPS fills

Overlap is measured at the condition-group level on drug forms with at least 100 MEPS fills. The 0.81 ceiling compares two MEPS survey periods with each other — the agreement any method can expect given survey noise.

MEPS has its limits — it's self-reported, it under-sees specialty and physician-administered drugs, and its condition coding is coarse — so it's a floor for agreement, not a ceiling for truth. That is why it is one gate of four, and why data-quality results for the published tables live on our public data quality page.

Explore the indication hierarchy

Browse the published vocabulary by body system and condition, open a concept to see its structure and ICD-10 landing codes, and see the leading drugs for it — or search for a drug to find the indications it leads.

Indication explorer
Loading the hierarchy…

Use it: tables and API

The indication layer ships as five tables — drug_indication, indication, indication_condition, condition, condition_icd10 — plus the derived drug_icd10_estimate. For one drug at a time, call the API:

GET /v1/drugs/828348/indications

{
  "drug": { "drug_id": 828348, "drug_name": "cyclobenzaprine hydrochloride 10 MG Oral Tablet" },
  "indication_count": 12,
  "indications": [
    {
      "indication_name": "Muscle spasm in acute low back pain",
      "pct_volume": 35.0,
      "use_type": "on_label",
      "relationship": "treats_symptom_of",
      "primary_condition": "acute low back pain",
      "target": "muscle spasm",
      "conditions": [{ "condition_name": "Low back pain",
                       "icd10_codes": [{ "code": "M54.50", "is_billable": true }] }]
    },
    …
  ]
}

Full field reference on the data model page and in the API reference.

Frequently asked questions

How do I map drugs to diseases or indications?

Normalize the drug to RxNorm, then join it to a source that gives each indication a weight — the share of the drug's prescriptions written for it — and names the condition the patient has rather than only what the drug acts on. Map that condition to ICD-10-CM (or SNOMED CT or MeSH) last. TwinFyRx publishes this as drug_indication and drug_icd10_estimate, keyed on the RxNorm drug_id, and through GET /v1/drugs/{drug_id}/indications.

Is there a free drug–indication database?

Yes: NLM's MED-RT relationships (available through the RxClass API) and FDA labeling via DailyMed and openFDA are free. They are useful for asking whether a drug can treat a condition. They don't weight indications, they cover off-label use only sparsely, and they code to the drug's target (nausea, muscle spasm) rather than the patient's diagnosis — so they can't tell you why a given prescription was written.

Is there a crosswalk from NDC or RxNorm to ICD-10 diagnosis codes?

No official one exists, because a drug maps to many diagnoses with different likelihoods. A usable crosswalk runs NDC → RxNorm drug → weighted indications → billable ICD-10-CM codes. TwinFyRx's drug_icd10_estimate table gives the share of each drug's prescriptions per billable ICD-10-CM code, derived from its indication layer.

How much of a drug's use is off-label?

It varies widely by drug. For gabapentin 300 mg capsules, the two FDA-labeled indications (postherpetic neuralgia and partial-onset seizures) account for about 10% of prescriptions in our estimates; the rest is off-label, led by painful diabetic neuropathy and lumbar radiculopathy. Each TwinFyRx indication row carries a use_type of on_label or off_label.

Can you infer a patient's diagnosis from a prescription?

Probabilistically. A drug's indication shares read as the probability that the patient behind a fill has each condition — for example, about 62% of cyclobenzaprine 10 mg fills are for neck or back pain. Combined with other claims and prescriptions, that is the basis for diagnosis suspecting; on its own it is a prior, not a diagnosis.

What is the difference between an indication and a diagnosis code?

An indication is the clinical reason for a drug — 'stroke prevention in atrial fibrillation.' A diagnosis code is how that reason is billed — I48.91 — and it drops the intent (prevention) and the target (stroke). TwinFyRx keeps the indication as its own concept and maps it to diagnosis codes as a separate step.

How are drug indication shares estimated?

Through a multi-stage, AI-assisted research workflow: frontier AI models, drawing on FDA labeling, clinical guidelines and the published real-world utilization literature, identify each drug's uses, on-label and off, and their share of prescriptions. Separate stages normalize those uses into a shared indication vocabulary, curate it, and code it to ICD-10-CM. Domain experts review the output, and every release is benchmarked against real-world prescription–diagnosis data from AHRQ MEPS.

How is TwinFyRx indication data validated?

Against the AHRQ Medical Expenditure Panel Survey (MEPS), which records the condition each household reported a prescription was for; through a random-sample clinical review before every publish; with an audit against a gold set of known errors; and with structural checks (shares sum to 100% per drug, every drug-level ICD-10 code is billable, every vocabulary change is logged).

Sources

  • MED-RT drug–disease relationships via the NLM RxClass API, retrieved September 2026.
  • Clinical Classifications Software Refined (CCSR) for ICD-10-CM Diagnoses. Healthcare Cost and Utilization Project (HCUP). Agency for Healthcare Research and Quality, Rockville, MD. hcup-us.ahrq.gov. TwinFyRx's condition layer is adapted from CCSR; it is not produced or endorsed by AHRQ.
  • Medical Expenditure Panel Survey (MEPS), Prescribed Medicines and Medical Conditions files. Agency for Healthcare Research and Quality. meps.ahrq.gov. Used for statistical benchmarking only.
  • ICD-10-CM, Centers for Medicare & Medicaid Services / National Center for Health Statistics.

Every tier gets the same indication data.

Tiers differ by refresh cadence, delivery and usage rights.

Get Access