healthcare.dev docs
API referenceDrugs

Search drug recalls

GET /v1/drugs/recalls

GET https://api.healthcare.dev/v1/drugs/recalls

FDA drug recalls from the weekly Enforcement Report (via openFDA). Filter by NDC, hazard class, status and report date, search text with q, or combine them. With q, results are ranked by match_score; without it, newest report first (match_score: 1). ndc matches at the product level.

Requires an API key: Authorization: Bearer hdev_live_.... See Authentication.

Query parameters

NameTypeRequiredDescriptionExample
qstringnoProduct, firm, reason or recall number (fuzzy, at least 3 characters)metformin
ndcstringnoProduct, package (any 10-digit layout) or 11-digit NDC. Matches at the product level: an entry for any package of the product, or linked to the product's label by openFDA.76385-129-01
classification"I" | "II" | "III"noFDA hazard class; I is the most seriousI
status"ongoing" | "completed" | "terminated"noRecall statusongoing
fromstring (date)noReported on or after this date (YYYY-MM-DD)2026-01-01
tostring (date)noReported on or before this date (YYYY-MM-DD)2026-12-31
limitintegernoPage size (max 100)25
cursorstringnoOpaque cursor from links.next
view"compact" | "full"nocompact returns only the fields an agent usually needs (fewer tokens); full (default) returns every fieldcompact
fieldsstringnoComma-separated record fields to return, e.g. code,display,billablecode,display,billable

Examples

curl

curl "https://api.healthcare.dev/v1/drugs/recalls?q=metformin&limit=25" \
  -H "Authorization: Bearer $HDEV_API_KEY"

TypeScript

const res = await fetch("https://api.healthcare.dev/v1/drugs/recalls?q=metformin&limit=25", {
  headers: { Authorization: `Bearer ${process.env.HDEV_API_KEY}` },
});
const { data, meta } = await res.json();

Python

import os
import requests

res = requests.get("https://api.healthcare.dev/v1/drugs/recalls?q=metformin&limit=25", headers={"Authorization": f"Bearer {os.environ['HDEV_API_KEY']}"})
body = res.json()

Try it

GEThttps://api.healthcare.dev/v1/drugs/recalls?q=metformin&ndc=76385-129-01&classification=I&status=ongoing&from=2026-01-01&to=2026-12-31&limit=25&view=compact&fields=code%2Cdisplay%2Cbillable
Get a free key
Copy as curl
curl "https://api.healthcare.dev/v1/drugs/recalls?q=metformin&ndc=76385-129-01&classification=I&status=ongoing&from=2026-01-01&to=2026-12-31&limit=25&view=compact&fields=code%2Cdisplay%2Cbillable" \
  -H "Authorization: Bearer $HDEV_API_KEY"

Response

Matching recalls

{
  "data": [
    {
      "id": "string",
      "recall_number": "string",
      "event_id": "string",
      "classification": "I",
      "status": "ongoing",
      "voluntary_mandated": "string",
      "recalling_firm": "string",
      "firm_location": {
        "city": "string",
        "state": "string",
        "postal_code": "string",
        "country": "string"
      },
      "product_description": "string",
      "product_quantity": "string",
      "reason_for_recall": "string",
      "code_info": "string",
      "distribution_pattern": "string",
      "initial_firm_notification": "string",
      "recall_initiation_date": "2026-10-01",
      "center_classification_date": "2026-10-01",
      "report_date": "2026-10-01",
      "termination_date": "2026-10-01",
      "ndcs": [
        "string"
      ],
      "ndc11s": [
        "string"
      ],
      "openfda": {
        "product_ndcs": [
          null
        ],
        "package_ndcs": [
          null
        ],
        "brand_names": [
          null
        ],
        "generic_names": [
          null
        ],
        "manufacturer_names": [
          null
        ],
        "rxcuis": [
          null
        ],
        "application_numbers": [
          null
        ],
        "spl_set_ids": [
          null
        ]
      },
      "match_score": 0
    }
  ],
  "meta": {
    "source": "cms-icd10",
    "data_version": "2026.1",
    "retrieved_at": "2026-10-24T12:00:00Z",
    "license": "Public domain (CMS). Reference data, not medical advice."
  },
  "links": {
    "self": "/v1/drugs/recalls?q=metformin&limit=25",
    "next": "/v1/drugs/recalls?q=metformin&limit=25&cursor=eyJrIjoiRTExLjkifQ"
  }
}

Fields

FieldTypeAlways presentDescription
idstringyesThe recall number, or E<event_id>-<8 hex> for the rare record FDA published without one
recall_numberstring | nullyesFDA recall number, usually D-NNNN-YYYY (older ones vary): one product in a recall event
event_idstringyesFDA recall event; one event can cover several products
classification"I" | "II" | "III" | nullyesFDA hazard class: I = reasonable probability of serious harm or death, II = temporary or reversible harm, III = unlikely to cause harm. null until FDA classifies it.
status"ongoing" | "completed" | "terminated"yesongoing = still in progress; completed = the firm finished, FDA has not closed it; terminated = FDA closed it
voluntary_mandatedstring | nullyese.g. Voluntary: Firm initiated or FDA Mandated
recalling_firmstringyes
firm_locationobjectyes
product_descriptionstringyes
product_quantitystring | nullyes
reason_for_recallstringyes
code_infostring | nullyesLot numbers and expiration dates covered
distribution_patternstring | nullyes
initial_firm_notificationstring | nullyes
recall_initiation_datestring | null (date)yes
center_classification_datestring | null (date)yes
report_datestring (date)yesWeekly FDA Enforcement Report that published it
termination_datestring | null (date)yes
ndcsstring[]yesPackage NDCs named in the product description, as written
ndc11sstring[]yesEvery package NDC above and in openfda, normalized to NDC-11
openfdaOpenFdaLinksyes
match_scorenumberyesHow well this result matches the query: 1 exact code or id, 0.9 code prefix, 0.5 to 0.9 every query word in the text (higher is closer), under 0.5 a fuzzy (typo-tolerant) match. Below 0.5, check the result before relying on it.

Errors

Errors are application/problem+json (RFC 9457). Branch on type, not on title. See Errors.

StatustypeWhen
400invalid-requestA parameter or the body failed validation; errors lists each field.
401unauthorizedMissing, malformed or revoked API key.
404not-foundNo record with that id (retired records are still returned).
429rate-limited / quota-exceededToo many requests per second (retry after Retry-After), or the monthly quota is used up.
503dataset-unavailable / unavailableThe dataset has no published version yet, or the service is degraded.

On this page