Know what's in shortage — and what changed — without five clicks.
An open, auto-updating dashboard for US drug shortages with git-diffable history and a machine-readable JSON/CSV API.
shortwatch answers one question fast: is this drug currently in shortage in the US, and when did that change? It pulls the openFDA Drug Shortages feed once a day, collapses it to one clean row per drug, and commits the snapshot to git — so the dashboard is always fresh and every change is a diff you can read.
Built for hospital and retail pharmacists, P&T committees, 340B / supply-chain teams, health-IT integrators, and clinical-AI builders who need a clean, queryable shortage feed.
The one thing no one else has — a permanent, open history. The FDA removes resolved shortages from its public list after about six months, and ASHP's historical data is licensed and copyright-locked. shortwatch commits a fresh snapshot every day, so it quietly builds the only free, queryable record of which drugs were short, when, and when they recovered — a
git logfor US drug shortages.
ℹ️ Informational tool only — not medical advice, not a diagnostic device, not for clinical decisions. See DISCLAIMER.md.
git clone https://github.com/acuestamd/shortwatch.git
cd shortwatch
python -m src.update # pulls openFDA → writes data/latest.json + latest.csv + history.json
python -m http.server 8000 # open http://localhost:8000 (index.html reads data/latest.json)Zero install, zero config — src/update.py uses only the Python standard library. Or skip all of it and open the live dashboard (GitHub Pages): it refreshes itself daily.
Want just the data? Point your tooling straight at the snapshot:
curl -s https://raw.githubusercontent.com/acuestamd/shortwatch/main/data/latest.json | python -m json.tool- One glance, not five clicks. Search and filter every shortage, then export the exact rows you see as CSV or JSON.
- A real "API," not a web page.
data/latest.jsonanddata/latest.csvare stable, machine-readable artifacts you can wire into a notebook, a P&T report, or an LLM pipeline. - Git-diffable history. Every daily snapshot is committed, so
git log -p data/latest.jsonshows precisely what entered shortage, what resolved, and when. Adata/history.jsonledger tracks first-seen / resolved dates per drug. - Honest counts. shortwatch separates a current shortage from a planned ("to be discontinued") discontinuation — so the headline number means what it says (more in Status taxonomy).
- Runs itself. A daily GitHub Action fetches, validates, and commits. No server, no database, no babysitting.
- Zero runtime dependencies. Pure standard library (
urllib,json,csv). Easy to trust, easy to audit, nothing to rot. - 🔔 Subscribe to changes.
data/feed.xml(Atom) anddata/events.jsonstream every drug that enters or leaves the shortage list — drop the feed into any RSS reader, Slack, or webhook. The diffable change log no official source publishes.
openFDA Drug Shortages API
│ (paged, polite, std-lib urllib)
▼
src/update.py
│ fetch_records() → collapse ~1,700 per-NDC rows into one row per drug
│ (generic name + dosage form), newest status wins
│ classify_status() → map raw FDA label → one canonical status
│ build_output() → assemble snapshot + summary counts
│
├──► data/latest.json structured snapshot (the dashboard reads this)
├──► data/latest.csv flat export, one row per drug
└──► data/history.json append-only first-seen / resolved ledger
▼
GitHub Action commits the diff daily ──► history is browsable in git
▼
index.html (static, no build step) ──► GitHub Pages
The collapse step is the value-add: openFDA returns one record per package NDC, so a single drug can appear a dozen times. shortwatch keys on (generic name, dosage form), keeps the most recently updated status, derives the earliest first_posted across NDCs, and unions therapeutic categories — turning a noisy feed into one trustworthy row per drug.
The FDA feed mixes current shortages with planned discontinuations. Counting them together overstates the problem — so shortwatch maps each raw status to exactly one canonical value:
status |
Maps from openFDA | Meaning |
|---|---|---|
current_shortage |
Current |
Actively in shortage right now. |
to_be_discontinued |
To Be Discontinued |
A planned discontinuation — not a current shortage. |
resolved |
Resolved |
Shortage has ended. |
discontinued |
(permanently unavailable) | No longer marketed. |
other |
anything else | Unmapped; the original label is always preserved in raw_status. |
Headline metric — "drugs currently in shortage" = count of
current_shortageonly.to_be_discontinuedis reported separately and is never folded into the shortage count. The raw FDA label is always kept verbatim inraw_statusso nothing is lost.
| Source | What it provides | Auth | Cadence | Status |
|---|---|---|---|---|
| openFDA Drug Shortages | Current / to-be-discontinued / resolved status, availability, manufacturer, therapeutic category, posting & update dates | None (public) | Daily, 06:00 UTC | Live (v0.1) |
| ASHP Drug Shortages | Often-richer clinical detail: reasons, estimated resupply, and management guidance; frequently lists shortages FDA does not | — | — | Roadmap |
openFDA reflects manufacturer-reported data submitted to the FDA. ASHP and FDA often disagree on what's in shortage; adding ASHP and flagging the discrepancies is the next big coverage win.
data/latest.json
data/latest.csv— the same records, flattened — drop straight into Excel, a notebook, or a BI tool.data/history.json— per-drug ledger offirst_seenandresolved_seen, the engine behind the diffable timeline.
- Informational / tooling only. Not medical advice, not a diagnostic device, not for clinical decision-making. See DISCLAIMER.md.
current_shortage≠to_be_discontinued. A drug flagged To Be Discontinued is a planned discontinuation, not a present shortage, and is excluded from the headline count. Filter onstatusdeliberately.- openFDA only (for now). Data is manufacturer-reported and can be incomplete or delayed. Shortages tracked solely by ASHP (or others) won't appear until that source lands.
resolveddetection is best-effort — driven by openFDA's ownResolvedstatus and by drops between snapshots.rxcuiand brand names come from openFDA enrichment and may be missing for some products.- Always verify against the primary FDA Drug Shortages database before acting on anything.
- ASHP as a second source, with FDA-vs-ASHP discrepancy flags
- RSS / JSON feed + webhook alerts for "newly added" and "newly resolved" shortages
- Embeddable status badge — drop a live "N drugs in shortage" badge into any README or wiki
- Per-drug detail pages with a status sparkline from
history.json - Therapeutic-category and dosage-form facet filters in the dashboard
Issues and PRs are welcome — start with CONTRIBUTING.md. If you find a wrong or stale data point, open an issue with a link to the primary source.
MIT © 2026 Armando Cuesta — see LICENSE.

{ "updated_utc": "2026-05-31T06:00:00+00:00", "source": "openFDA Drug Shortages API", "source_url": "https://open.fda.gov/apis/drug/shortages/", "disclaimer": "Informational use only. Not medical advice ...", "summary": { "current_shortage": 0, // ← the headline number "to_be_discontinued": 0, // tracked separately, never added in "resolved": 0, "discontinued": 0, "other": 0, "total": 0 }, "count": 0, "records": [ { "drug": "Amoxicillin Capsule", "status": "current_shortage", // canonical (see taxonomy) "raw_status": "Current", // verbatim FDA label, always preserved "therapeutic_category": ["Anti-Infective"], "first_posted": "2025-01-14", "resolved_date": null, // present only when resolved "manufacturer": "Example Pharma", "brand_name": "EXAMPLE", "rxcui": "723", "ndc_count": 6 } ] }