Nearly 1 in 4 Americans takes a prescription drug alongside a dietary supplement. That's roughly 75 million people who might not know that their fish oil could be amplifying their blood thinner, or that their St. John's Wort is undermining their antidepressant.
If you're building a health app, a pharmacy tool, or any patient-facing software, drug interaction checking isn't a nice-to-have -- it's table stakes.
The problem is that getting reliable interaction data into your app has historically been painful.
The Problem: Separate Databases, None of Them Talk to Each Other
The US government maintains excellent drug and supplement data. It's authoritative, it's free, and it's scattered across separate systems with different formats:
- openFDA (api.fda.gov) -- drug labels, NDC directory, drug-interaction label sections, adverse events
- RxNorm (rxnav.nlm.nih.gov) -- drug naming and RxCUI identifiers
- NIH ODS (ods.od.nih.gov) -- supplement fact sheets and interactions
Each API has its own conventions, its own data format, and its own quirks. RxNorm uses RxCUI identifiers. openFDA uses NDC codes. NIH supplement data comes in yet another format. To get a complete picture of a drug plus its supplement interactions, you need to cross-reference all of them.
Most teams either spend weeks building and maintaining their own integration layer, or they pay $500+/month for a commercial database license. Neither option is great for a side project, an MVP, or a startup trying to validate an idea.
MedData API: One Endpoint, All the Data
MedData API unifies these government databases into a single REST API. You get drug search, supplement lookup, and interaction checking through clean, consistent endpoints.
It's built by Anthesia and runs on the actual government data sources -- nothing is generated or inferred. Drug-drug interactions come from FDA structured product labels (openFDA) plus a curated set of major interactions; drug-supplement interactions come from the NIH.
Let me show you how it works.
Quick Start
You'll need an API key. The free tier gives you 250 requests/month, which is enough to test everything out.
- Go to the API docs
- Generate your API key via the
/api/v1/billing/subscribeendpoint or contact support for a free-tier key - Pass your key in the
X-API-Keyheader on every request
All set. Let's write some code.
Example 1: Search for a Drug
Let's start simple -- search for "metformin" and get back structured data.
Python (httpx)
import httpx
API_KEY = "your_api_key_here"
BASE_URL = "https://meddata.anthesia.io"
async def search_drug(name: str):
async with httpx.AsyncClient() as client:
response = await client.get(
f"{BASE_URL}/api/v1/drugs/search",
params={"name": name, "limit": 5},
headers={"X-API-Key": API_KEY},
)
response.raise_for_status()
data = response.json()
for drug in data["results"]:
print(f"{drug['brand_name']} ({drug['generic_name']})")
print(f" RxCUI: {drug['rxcui']}")
print(f" Maker: {drug['manufacturer']}")
print()
return data
# Run it
import asyncio
asyncio.run(search_drug("metformin"))
JavaScript (fetch)
const API_KEY = "your_api_key_here";
const BASE_URL = "https://meddata.anthesia.io";
async function searchDrug(name) {
const params = new URLSearchParams({ name, limit: "5" });
const response = await fetch(
`${BASE_URL}/api/v1/drugs/search?${params}`,
{ headers: { "X-API-Key": API_KEY } }
);
if (!response.ok) {
throw new Error(`API error: ${response.status}`);
}
const data = await response.json();
for (const drug of data.results) {
console.log(`${drug.brand_name} (${drug.generic_name})`);
console.log(` RxCUI: ${drug.rxcui}`);
console.log(` Maker: ${drug.manufacturer}`);
}
return data;
}
searchDrug("metformin");
The response looks like this:
{
"results": [
{
"rxcui": "6809",
"brand_name": "Riomet",
"generic_name": "METFORMIN HYDROCHLORIDE",
"dosage_form": null,
"strength": null,
"manufacturer": "Sun Pharmaceutical Industries, Inc."
}
],
"total_count": 1,
"query": "metformin"
}
Heads up: dosage_form and strength aren't populated for every drug yet and can come back null. The reliably present fields are brand name, generic name, RxCUI, and manufacturer.
The API checks its local cache first (fast), then hits openFDA and RxNorm if needed (slower on first request, cached for subsequent calls).
Example 2: Check Warfarin + Supplement Interactions
This is where it gets interesting. Warfarin is one of the most interaction-prone drugs out there. Let's check it against a few supplements a patient might be taking.
Python
async def check_warfarin_supplements():
async with httpx.AsyncClient() as client:
response = await client.get(
f"{BASE_URL}/api/v1/interactions/supplements",
params={
"drugs": "warfarin",
"supplements": "Fish Oil,Vitamin D,St. John's Wort",
},
headers={"X-API-Key": API_KEY},
)
response.raise_for_status()
data = response.json()
print(f"Checked {data['item_count']} items")
print(f"Found {len(data['interactions'])} interactions:\n")
for interaction in data["interactions"]:
print(f" {interaction['item_1_name']} + {interaction['item_2_name']}")
print(f" Severity: {interaction['severity']}")
print(f" {interaction['description']}")
print(f" Source: {interaction['source']}")
print()
asyncio.run(check_warfarin_supplements())
JavaScript
async function checkWarfarinSupplements() {
const params = new URLSearchParams({
drugs: "warfarin",
supplements: "Fish Oil,Vitamin D,St. John's Wort",
});
const response = await fetch(
`${BASE_URL}/api/v1/interactions/supplements?${params}`,
{ headers: { "X-API-Key": API_KEY } }
);
const data = await response.json();
console.log(`Checked ${data.item_count} items`);
console.log(`Found ${data.interactions.length} interactions:\n`);
for (const ix of data.interactions) {
console.log(` ${ix.item_1_name} + ${ix.item_2_name}`);
console.log(` Severity: ${ix.severity}`);
console.log(` ${ix.description}`);
console.log(` Source: ${ix.source}\n`);
}
}
checkWarfarinSupplements();
There's also a unified endpoint at /api/v1/interactions/check that auto-detects whether each item is a drug or supplement. Just pass a comma-separated list:
GET /api/v1/interactions/check?items=warfarin,aspirin,Fish Oil
It figures out that warfarin and aspirin are drugs (resolves them via RxNorm) and Fish Oil is a supplement, then checks all pairwise interactions across both categories.
Example 3: Batch Check Multiple Pairs
If your app needs to check a patient's entire medication list, use the batch endpoint. It checks up to 50 pairs in a single request.
Python
async def batch_interaction_check():
async with httpx.AsyncClient() as client:
response = await client.post(
f"{BASE_URL}/api/v1/batch/interactions",
json={
"pairs": [
["aspirin", "ibuprofen"],
["warfarin", "Fish Oil"],
["metformin", "alcohol"],
["lisinopril", "potassium"],
["simvastatin", "amiodarone"],
]
},
headers={"X-API-Key": API_KEY},
)
response.raise_for_status()
data = response.json()
print(f"Checked {data['total_pairs_checked']} pairs")
print(f"Found {data['total_interactions_found']} interactions")
print(f"Used {data['queries_used']} API queries\n")
for result in data["results"]:
pair_label = " + ".join(result["items"])
if result["interactions"]:
for ix in result["interactions"]:
print(f" {pair_label}: {ix['severity']} - {ix['description'][:80]}...")
else:
print(f" {pair_label}: No interactions found")
asyncio.run(batch_interaction_check())
JavaScript
async function batchInteractionCheck() {
const response = await fetch(
`${BASE_URL}/api/v1/batch/interactions`,
{
method: "POST",
headers: {
"X-API-Key": API_KEY,
"Content-Type": "application/json",
},
body: JSON.stringify({
pairs: [
["aspirin", "ibuprofen"],
["warfarin", "Fish Oil"],
["metformin", "alcohol"],
["lisinopril", "potassium"],
["simvastatin", "amiodarone"],
],
}),
}
);
const data = await response.json();
console.log(`Checked ${data.total_pairs_checked} pairs`);
console.log(`Found ${data.total_interactions_found} interactions`);
console.log(`Used ${data.queries_used} API queries\n`);
for (const result of data.results) {
const label = result.items.join(" + ");
if (result.interactions.length > 0) {
for (const ix of result.interactions) {
console.log(` ${label}: ${ix.severity} - ${ix.description.slice(0, 80)}...`);
}
} else {
console.log(` ${label}: No interactions found`);
}
}
}
batchInteractionCheck();
Each pair counts as one API call against your quota, so checking 5 pairs uses 5 calls.
What's in the Database
Here's a snapshot of the data available right now:
- 120+ supplements with dosage info, evidence summaries, and known interactions (sourced from NIH ODS)
- 100,000+ drugs searchable by brand name, generic name, RxCUI, or NDC code
- 250+ verified drug-supplement interactions curated from NIH and FDA sources
- Drug-drug interactions from FDA structured product labels (openFDA) plus a curated set of major, clinically significant interactions
All interaction data comes from established medical databases. Nothing is generated or inferred -- that's important when you're dealing with patient safety.
How It Compares
| Feature | MedData API | DrugBank API | DIY (build it yourself) |
|---|---|---|---|
| Drug search | Yes | Yes | Weeks of integration work |
| Supplement data | Yes (120+ supplements) | Limited | Separate NIH integration |
| Drug-drug interactions | Yes (FDA labels + curated) | Yes | Build it yourself |
| Drug-supplement interactions | Yes (250+ verified) | Limited | Manual curation needed |
| Unified drug + supplement check | Yes (auto-detects) | No | Custom logic required |
| Batch checking | Yes (50 pairs/request) | Varies | Build your own |
| Free tier | 250 calls/month | No free tier | Free (but your time isn't) |
| Starting price | $29/month | $500+/month | $0 + engineering time |
| Setup time | 5 minutes | Hours | Weeks |
Pricing
Straightforward per-month pricing, no per-call fees within your tier:
| Plan | Requests/Month | Price |
|---|---|---|
| Free | 250 | $0 |
| Starter | 5,000 | $29/mo |
| Growth | 25,000 | $79/mo |
| Business | 100,000 | $199/mo |
| Enterprise | 100,000+ | Custom (support@anthesia.io) |
The free tier is there so you can test everything before committing. No credit card required.
API Design Notes
A few decisions worth mentioning if you're evaluating this for production use:
-
Authentication is via
X-API-Keyheader (SHA-256 hashed on the server, never stored in plaintext) - Caching is aggressive -- drug data is cached for 7 days, interactions for 30 days, pricing for 24 hours. First requests are slower; subsequent ones are fast
-
Error responses follow a consistent format:
{error, detail, status_code, request_id}. The request_id is useful for debugging - Rate limiting is per-API-key, tracked monthly with automatic reset
-
OpenAPI docs are auto-generated -- the Swagger UI at
/docsis fully interactive
Disclaimer
This API provides drug and supplement information for informational purposes only. It is not medical advice. Always consult a qualified healthcare professional before making clinical decisions. All interaction data is sourced from established government and medical databases (RxNorm, NIH, FDA) -- nothing is generated or inferred.
Try It Out
The API is live right now:
- Try it live (no signup, no code): anthesia.io/meddata/demo
- Interactive docs: https://meddata.anthesia.io/docs
- Health check: https://meddata.anthesia.io/health
- On RapidAPI: rapidapi.com/anthesiallc/api/meddata (if you'd rather manage keys and billing through a marketplace)
Grab a free API key, run through the examples above, and see if it fits what you're building. If you have questions or feature requests, drop a comment below.
Built by Anthesia. Data sourced from openFDA, RxNorm, and the NIH Office of Dietary Supplements.
Top comments (0)