Drug labels, adverse-event reports and recalls — as typed values, keyless, on any Apple platform.
import OpenFDAMetadata
let fda = OpenFDA()
let labels = try await fda.labels(forDrug: "Ozempic", limit: 1)
print(labels.results.first?.openfda?.label) // OZEMPIC (ORAL SEMAGLUTIDE)
print(labels.results.first?.hasBoxedWarning) // true
// openFDA's own aggregation — one request, not thousands
let top = try await fda.topReactions(forDrug: "Ozempic", limit: 5)
// NAUSEA (9751), OFF LABEL USE (6949), VOMITING (6341), …- 💊 Three databases, one client — Structured Product Labels, FAERS adverse events, and enforcement reports for drugs, devices and food
- 🔤 A search builder with tests — openFDA's
searchis a Lucene expression whose failure mode is silent: an unquoted value with a space matches the first word only and returns a cheerful HTTP 200 full of the wrong rows.Queryquotes and escapes, and the tests are the point of the library - ➕ Operators survive the URL —
+AND+and+TO+are syntax, not data.URLComponentswould percent-encode those+signs and break every compound query, so the query string is assembled deliberately - 📊
topReactionsuses the API's aggregation — "what do people report about this drug" becomes one request instead of paging sixty thousand reports - 🏷️ The
openfdablock modelled properly — brand and generic names, manufacturer, route, NDC, RxCUI, UNII, pharmacologic class. Every field is an array upstream, including the ones that read as singular, and the accessors say so - 🚨 Class I recalls are recognised without swallowing II and III — the numbering runs opposite to most severity scales, and prefix matching gets it wrong
- 🔁 Paging that terminates — an empty page ends the walk whatever the total claims, and
hasMorerespects openFDA's own 25,000-row skip cap - 🔑 The key is optional — 1,000 requests a day per IP without one, 120,000 with. Nothing here requires it
- 📼 Tested on recordings — 18 tests on real captured output with an injected transport. No network, no spent budget
FAERS reports are spontaneous and unverified. A report says somebody told the FDA that something happened while a drug was being taken — not that the drug caused it. Counts are not comparable between drugs, because reporting rates differ enormously with a drug's age, publicity and litigation history. openFDA says as much in every response's disclaimer, and anything surfacing these numbers to people should repeat it.
macOS 14+ / iOS 16+ / tvOS 16+ / watchOS 9+ / visionOS 1+, Swift 6. Foundation only.
MIT — see LICENSE.