API referenceDrugs
Search drug recalls
GET /v1/drugs/recalls
GET https://api.healthcare.dev/v1/drugs/recallsFDA 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
| Name | Type | Required | Description | Example |
|---|---|---|---|---|
q | string | no | Product, firm, reason or recall number (fuzzy, at least 3 characters) | metformin |
ndc | string | no | Product, 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" | no | FDA hazard class; I is the most serious | I |
status | "ongoing" | "completed" | "terminated" | no | Recall status | ongoing |
from | string (date) | no | Reported on or after this date (YYYY-MM-DD) | 2026-01-01 |
to | string (date) | no | Reported on or before this date (YYYY-MM-DD) | 2026-12-31 |
limit | integer | no | Page size (max 100) | 25 |
cursor | string | no | Opaque cursor from links.next | |
view | "compact" | "full" | no | compact returns only the fields an agent usually needs (fewer tokens); full (default) returns every field | compact |
fields | string | no | Comma-separated record fields to return, e.g. code,display,billable | code,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
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
| Field | Type | Always present | Description |
|---|---|---|---|
id | string | yes | The recall number, or E<event_id>-<8 hex> for the rare record FDA published without one |
recall_number | string | null | yes | FDA recall number, usually D-NNNN-YYYY (older ones vary): one product in a recall event |
event_id | string | yes | FDA recall event; one event can cover several products |
classification | "I" | "II" | "III" | null | yes | FDA 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" | yes | ongoing = still in progress; completed = the firm finished, FDA has not closed it; terminated = FDA closed it |
voluntary_mandated | string | null | yes | e.g. Voluntary: Firm initiated or FDA Mandated |
recalling_firm | string | yes | |
firm_location | object | yes | |
product_description | string | yes | |
product_quantity | string | null | yes | |
reason_for_recall | string | yes | |
code_info | string | null | yes | Lot numbers and expiration dates covered |
distribution_pattern | string | null | yes | |
initial_firm_notification | string | null | yes | |
recall_initiation_date | string | null (date) | yes | |
center_classification_date | string | null (date) | yes | |
report_date | string (date) | yes | Weekly FDA Enforcement Report that published it |
termination_date | string | null (date) | yes | |
ndcs | string[] | yes | Package NDCs named in the product description, as written |
ndc11s | string[] | yes | Every package NDC above and in openfda, normalized to NDC-11 |
openfda | OpenFdaLinks | yes | |
match_score | number | yes | How 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.
| Status | type | When |
|---|---|---|
| 400 | invalid-request | A parameter or the body failed validation; errors lists each field. |
| 401 | unauthorized | Missing, malformed or revoked API key. |
| 404 | not-found | No record with that id (retired records are still returned). |
| 429 | rate-limited / quota-exceeded | Too many requests per second (retry after Retry-After), or the monthly quota is used up. |
| 503 | dataset-unavailable / unavailable | The dataset has no published version yet, or the service is degraded. |