Docs / Get started

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_…"

Call GET /v1/drugs with a country code and a query:

GET /v1/drugs
curl -G https://api.medifontis.com/v1/drugs \
  -H "Authorization: Bearer $MEDIFONTIS_API_KEY" \
  --data-urlencode "country=ca" \
  --data-urlencode "q=metformin"

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.

First result
{
  "country": "ca",
  "sourceId": "ca.health-canada.dpd",
  "id": "ca:health-canada:products:62265",
  "kind": "products",
  "name": "METFORMIN · 500 MG per TAB · TABLET",
  "data": {
    "din": "02238827",
    "form": "TABLET",
    "name": "METFORMIN · 500 MG per TAB · TABLET",
    "holder": "LABORATOIRES CONFAB INC",
    "routes": [
      "ORAL"
    ],
    "smpcUrl": null,
    "atcCodes": [
      "A10BA02"
    ],
    "drugCode": "62265",
    "marketed": false,
    "packages": [],
    "brandName": "METFORMIN",
    "updatedAt": "22-MAR-2025",
    "useDomain": "human",
    "descriptor": null,
    "leafletUrl": null,
    "statusDate": "09-APR-2021",
    "biosimilars": [],
    "brandNameFr": null,
    "descriptorFr": null,
    "productClass": "Human",
    "publishedDin": "02238827",
    "sourceStatus": "CANCELLED PRE MARKET",
    "supplyRegime": "PRESCRIPTION",
    "targetSpecies": [],
    "categorization": null,
    "ingredientGroup": "0101773001",
    "publicationDate": "2026-10-05",
    "sourcePartition": "cancelled",
    "dinNotApplicable": false,
    "activeIngredients": [
      {
        "base": "N",
        "code": "10147",
        "name": "METFORMIN HYDROCHLORIDE",
        "unit": "MG",
        "nameFr": "Chlorhydrate de metformine",
        "strength": "500",
        "dosageUnit": "TAB",
        "dosageValue": null,
        "strengthType": null,
        "suppliedIndicator": "I"
      }
    ],
    "useDomainEvidence": {
      "basis": "publisher-field",
      "field": "class",
      "value": "Human",
      "version": 1,
      "sourceId": "ca.health-canada.dpd"
    },
    "identifierWarnings": [],
    "patientEligibility": "not-assessed",
    "numberOfIngredients": "1",
    "targetSpeciesStatus": "not-applicable",
    "administrativeStatus": "cancelled",
    "prescriptionCategory": "prescription-or-restricted",
    "prescriptionRequired": true,
    "pharmaceuticalStandards": []
  },
  "region": null,
  "retrievedAt": "2026-10-20T06:46:39.902Z",
  "sourceUrl": "https://www.canada.ca/en/health-canada/services/drugs-health-products/drug-products/drug-product-database/what-data-extract-drug-product-database.html",
  "licence": {
    "id": "LicenseRef-Health-Canada-DPD-Reuse-Unconfirmed",
    "url": "https://healthycanadians.gc.ca/important-eng.php",
    "reviewedAt": "2026-10-01",
    "attribution": "Source: Health Canada, Drug Product Database (DPD).",
    "documentsIncluded": false
  },
  "limitations": [
    "This is the complete published DPD extract, not the separately licensed natural health products database, the CCDD clinical terminology dataset or provincial formulary eligibility.",
    "The publisher page advertises file dates independently of the products’ own last-update dates; neither is silently replaced by collection time.",
    "Record identity is DRUG_CODE. DINs are verbatim eight-digit strings and can repeat across historical observations; Not Applicable/non applicable is retained but never indexed as a DIN.",
    "Veterinary and disinfectant products are collected as separate kinds and excluded from Doctofam prescriptions. Radiopharmaceuticals retain their own kind.",
    "Schedules C/D, homeopathic and prescription-recommended designations alone do not establish Rx/OTC classification; missing, mixed and unrecognised classifications remain unknown. Ethical is federally non-prescription professional use.",
    "Package descriptions and UPC values are publisher observations, not unique package records. No pack identifier, interchangeability, stock or patient eligibility is inferred.",
    "The actual therapeutic-class export has four columns rather than the current read-me’s seven; the fourth remains raw without an inferred meaning.",
    "Corporate addresses are withheld from normalized and raw records. Original source archives remain retained as evidence. No product monograph URLs are published in these extracts, and no clinical documents are copied.",
    "The linked legacy copyright notice requires permission for commercial reproduction. The Open Government portal also lists this dataset, but its current licence could not be verified during review; commercial derived-data reuse remains unconfirmed and the owner accepts this documented rights gap under the country brief."
  ],
  "names": [
    "METFORMIN · 500 MG per TAB · TABLET",
    "METFORMIN",
    "METFORMIN HYDROCHLORIDE",
    "Chlorhydrate de metformine"
  ],
  "identifiers": [
    {
      "value": "02238827",
      "scheme": "din"
    },
    {
      "value": "62265",
      "scheme": "dpd-drug-code"
    },
    {
      "value": "A10BA02",
      "scheme": "atc"
    },
    {
      "value": "0101773001",
      "scheme": "aig"
    }
  ]
}

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:

Node.js
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
  }
}

Next steps