Methodology
How MarkupRx actually works.
How we compute the leak figures
The figures on the homepage are illustrative examples of the kind of monthly margin shortfall MarkupRx surfaces on real claims. The actual numbers your pharmacy sees depend on contract mix, dispense volume, and PBM. The underlying formula (NADAC − reimbursement = margin) is the same across illustrative and real cases. See the NADAC section below for the method.
Read the technical detail
Each leak figure on the homepage is an example computed from the same margin = (total_amount_reimbursed / units_reimbursed) - nadac_per_unit formula documented in NADAC pricing & underwater detection. Per-pharmacy results vary by claim mix.
NADAC pricing & underwater detection
Every week, CMS publishes the National Average Drug Acquisition Cost (NADAC) — what pharmacies actually pay wholesalers per unit, surveyed across the country. We join NADAC against CMS State Drug Utilization Data (SDUD) to flag every claim-NDC pair where the pharmacy dispensed at a loss. No estimates, no proxy metrics — both sources are government-published and freely available.
Read the technical detail
The underwater margin formula is computed per claim-NDC pair from SDUD joined against the latest NADAC entry per NDC:
margin = (total_amount_reimbursed / units_reimbursed) - nadac_per_unitA negative margin = the pharmacy lost money dispensing that prescription.
- NADAC source: data.cms.gov/nadac — refreshed weekly by CMS; ~34,000 NDCs covered.
- SDUD source: medicaid.gov/sdud — quarterly Medicaid fee-for-service and managed care reimbursement at the NDC level; ~700,000 rows per quarter.
- Unit reconciliation: NADAC and SDUD must share the same pricing unit (EA, ML, etc.) for the margin to be valid. NDCs with mixed pricing units are excluded from underwater detection rather than risk a misleading comparison.
Live freshness for all 13 sources is on our /sources page. Underwater rankings by NDC and state are publicly viewable (no login) in the data explorer.
How MarkupRx generates appeals
When you're underwater on a claim, most states' PBM transparency laws give you the right to appeal a MAC reimbursement that falls below your documented acquisition cost. We draft the appeal letter for you — citing your actual claim data, the NADAC benchmark, and published Medicaid rates. You review and submit. AI assists; you stay in control.
Read the technical detail
Appeals are generated by Anthropic Claude Haiku 4.5 with structured-output JSON (no streaming, no chatbot). The prompt assembles your claim record, the relevant NADAC entries, and the state Medicaid pricing context from CMS SDUD, then produces an appeal letter tailored to the PBM's appeal process.
The appeal letter cites:
- The specific NDC and fill date from your dispensing data
- The NADAC acquisition-cost benchmark as of the fill date (point-in-time, not current NADAC — the defensible figure for an appeal is what NADAC said on the date of the fill)
- The SDUD reimbursement rate for that NDC in your state
- The per-fill loss amount (NADAC minus reimbursement)
See a full sample on our samples page or read the step-by-step appeal process guide on the blog.
Compliance signing & audit verification
Every audit bundle MarkupRx produces — quarterly margin reports, contract analyses, appeal exports — is cryptographically signed. You (or your auditor) can verify any document came from MarkupRx and hasn't been tampered with.
Read the technical detail
Two signing systems are in use:
- Ed25519 (legacy): bundles signed before our KMS migration use this curve. Download the legacy public key.
- AWS KMS P-256 (current): all new bundles use this hardware-backed key with CloudTrail WORM audit trail. Download the current public key.
Verify any audit bundle yourself with verify-audit-bundle.py and the public key linked above.
python verify-audit-bundle.py audit-bundle.zip --key compliance-public-key-kms-p256.pemAI analysis — attribution & constraints
AI analysis is by Anthropic Claude. Final outputs are reviewed by you.
Analysis outputs are structured JSON — no streaming, no chatbot, no free-form generation. Every AI response is constrained by an explicit JSON schema before it ever reaches you.
Read the technical detail
We use Claude Haiku 4.5 (claude-haiku-4-5-20251001) with a $50/month spend cap. When the monthly budget is exhausted, AI features gracefully degrade — cached responses still serve, but new analyses pause until the next billing month. Spend is tracked per request and aggregated daily.
All 13 federal data sources
Every data point in MarkupRx comes from a named U.S. government source. No proprietary data. No AWP (which is Medi-Span / First Databank proprietary). No WAC. Every figure is publicly verifiable at the source URL.
Read the technical detail
The 13 sources we integrate, with their update cadence:
- CMS NADAC — weekly pharmacy acquisition costs, ~34,000 NDCs (data.cms.gov/nadac)
- CMS SDUD — quarterly Medicaid reimbursement at NDC level (medicaid.gov/sdud)
- FDA NDC Directory — weekly drug identification (openFDA bulk JSON)
- FDA Orange Book — weekly patents and exclusivity for GenericWatch
- CMS Federal Upper Limit — monthly Medicaid ceiling pricing
- CMS ASP — quarterly Medicare Part B pricing
- VA FSS — semi-monthly VA Federal Supply Schedule contract prices
- IRA Negotiated Prices (MFP) — as published (~125 drugs, IRA-negotiated)
- CMS Drug Spending (Part B, Part D, Medicaid) — annual spending by drug
- FDA Drug Shortages — weekly supply disruptions via openFDA API
- Drugs@FDA — weekly approval history (7 tab-delimited files)
- RxNorm (NLM) — monthly RXCUI entity resolution (RXNSAT.RRF + RXNCONSO.RRF)
- HCPCS Crosswalk — quarterly NDC → Medicare Part B code mapping
All sources are joined through RxNorm RXCUI — the NLM's canonical drug entity identifier — so a NADAC NDC, an Orange Book patent, and an ASP billing code all resolve to the same drug concept. We never use fuzzy text matching for pharmaceutical name resolution.
Data source freshness
We integrate 13 federal data sources. Each has its own update cadence, from weekly (NADAC, NDC Directory, Orange Book, Drug Shortages) to annually (CMS Drug Spending). Freshness is monitored continuously.
Read the technical detail
Visit our /sources page for the live freshness table — updated every 5 minutes from our pipeline. Or explore the current underwater rankings in the public data explorer — refreshed weekly when CMS publishes new NADAC data.
For background on the NADAC vs. MAC gap mechanism, see the NADAC vs PBM Reimbursement explainer on the blog.
Ten minutes to know.
Read the report. Draft an appeal. Renegotiate a contract. Cancel if it isn't worth it.
15-day trial · no credit card · cancel anytime