Quickstart
Get an API key, search a medicine and read the result. It takes about five minutes.
1. Get an API key
Create a key on the signup page. It starts with mf_live_ and works immediately for every country. Get your API key.
Store it in an environment variable on your server:
export MEDIFONTIS_API_KEY="mf_live_…"
2. Search a medicine
Call GET /v1/drugs with a country code and a query:
curl -G https://api.medifontis.com/v1/drugs \
-H "Authorization: Bearer $MEDIFONTIS_API_KEY" \
--data-urlencode "country=us" \
--data-urlencode "q=atorvastatin"const params = new URLSearchParams({ country: 'us', q: 'atorvastatin' })
const response = await fetch(`https://api.medifontis.com/v1/drugs?${params}`, {
headers: { Authorization: `Bearer ${process.env.MEDIFONTIS_API_KEY}` },
})
if (!response.ok) throw new Error(`Medifontis ${response.status}`)
const { results, nextOffset } = await response.json()import os
import requests
response = requests.get(
"https://api.medifontis.com/v1/drugs",
params={"country": "us", "q": "atorvastatin"},
headers={"Authorization": f"Bearer {os.environ['MEDIFONTIS_API_KEY']}"},
timeout=10,
)
response.raise_for_status()
results = response.json()["results"]
3. Read the response
Each result is one record of one source. The fields you will use most are name, identifiers, sourceId and kind, data and licence.
{
"country": "us",
"sourceId": "us.fda.ndc",
"id": "us:fda:ndc:0078-1371_b0a6d76c-cacb-4499-a18a-c8353db652f2",
"kind": "ndc-products",
"name": "atorvastatin",
"data": {
"name": "atorvastatin",
"splId": "b0a6d76c-cacb-4499-a18a-c8353db652f2",
"labels": [],
"routes": [],
"labeler": "Novartis Pharmaceuticals Corporation",
"finished": false,
"packaging": [
{
"description": "5 kg in 1 BAG (0078-1371-07)",
"package_ndc": "0078-1371-07",
"identifierStatus": "well-formed",
"marketing_start_date": "19-SEP-13"
}
],
"productId": "0078-1371_b0a6d76c-cacb-4499-a18a-c8353db652f2",
"useDomain": "unknown",
"dosageForm": "POWDER",
"productNdc": "0078-1371",
"deaSchedule": null,
"genericName": "atorvastatin",
"productType": "BULK INGREDIENT",
"listingStatus": "present-in-source-snapshot",
"targetSpecies": [],
"approvalStatus": "not-established-by-ndc-listing",
"labelAssociation": "openFDA-harmonized-set-ids; not a product-level approval match",
"marketingEndDate": null,
"activeIngredients": [
{
"name": "ATORVASTATIN CALCIUM TRIHYDRATE",
"strength": "1 kg/kg"
}
],
"applicationNumber": null,
"marketingCategory": "BULK INGREDIENT",
"stateRestrictions": {
"status": "not-collected",
"observations": []
},
"useDomainEvidence": {
"basis": "unreviewed",
"field": null,
"value": null,
"version": 1,
"sourceId": "us.fda.ndc"
},
"marketingStartDate": "20130919",
"targetSpeciesStatus": "not-reported",
"prescriptionCategory": "unknown",
"harmonizedIdentifiers": {},
"listingExpirationDate": "20261231"
},
"region": null,
"retrievedAt": "2026-10-20T10:45:50.815Z",
"sourceUrl": "https://api.fda.gov/download.json",
"licence": {
"id": "CC0-1.0",
"url": "https://open.fda.gov/license/",
"attribution": "U.S. Food and Drug Administration / openFDA",
"documentsIncluded": false
},
"limitations": [
"Complete published endpoint, not a claim that FDA lists every medicine used in the US.",
"NDC listing, marketing category and application-number assertions are not proof of approval.",
"Tentative approval, discontinued products and historical submissions remain distinct.",
"Official document links only; linked documents have not been relicensed or mirrored.",
"No state restrictions, individual eligibility, or prescribing recommendations inferred.",
"UNII and RxNorm identifiers are source-asserted openFDA harmonization at record scope; arrays do not pair identifiers to individual products or ingredients, and are not GSID/PhPID or substitution evidence."
],
"names": [
"atorvastatin",
"ATORVASTATIN CALCIUM TRIHYDRATE"
],
"identifiers": [
{
"value": "0078-1371",
"scheme": "ndc-product"
},
{
"value": "0078-1371-07",
"scheme": "ndc-package"
},
{
"value": "b0a6d76c-cacb-4499-a18a-c8353db652f2",
"scheme": "spl-id"
}
]
}
4. Page through results
nextOffset is the offset of the next page, or null on the last one. Pass it as offset to read the next page:
async function* searchAll(country, q) {
let offset = 0
while (offset !== null) {
const params = new URLSearchParams({ country, q, limit: '50', offset: String(offset) })
const response = await fetch(`https://api.medifontis.com/v1/drugs?${params}`, {
headers: { Authorization: `Bearer ${process.env.MEDIFONTIS_API_KEY}` },
})
if (!response.ok) throw new Error(`Medifontis ${response.status}`)
const page = await response.json()
yield* page.results
offset = page.nextOffset
}
}