openfda_enforcement
Search FDA recall and enforcement records for drugs, devices, or foods. Filter by firm, product, reason, classification, status, and state.
Instructions
Search openFDA recall/enforcement records — drug/device/food product recalls with the recalling firm, product, reason, FDA classification (Class I/II/III), status, and geography (openFDA /{category}/enforcement.json; api.fda.gov). KEYLESS (an OPTIONAL free OPENFDA_API_KEY only RAISES the rate limit — keyless works at ~1000 requests/day; it NEVER throws for a missing key; get one at https://open.fda.gov/apis/authentication/; call api_key_status to see every source's key requirement). Input: category (drug|device|food, default drug), and STRUCTURED filters — firm (→recalling_firm), product (→product_description), reason (→reason_for_recall), classification (Class I|II|III), status (e.g. Ongoing/Terminated/Completed), state (2-letter, e.g. 'CA') — the tool safely assembles + escapes these into the openFDA search= Lucene string (NO raw passthrough — injection-safe), plus limit (1..100, default 25) and skip (offset ≥0). Returns { recalls:[{ recallingFirm, productDescription, reasonForRecall, classification, status, state, city, recallInitiationDate, recallNumber, voluntaryMandated, distributionPattern }] } + honest _meta. HONESTY: totalAvailable is openFDA's EXACT meta.results.total (skip/limit pagination via hasMore/nextOffset — never results.length); every scalar (dates included, recall_initiation_date is a YYYYMMDD string) is null-never-empty-string. ★A no-match query returns openFDA HTTP 404 NOT_FOUND ⇒ an HONEST EMPTY (returned:0, totalAvailable:0), NOT an error; a 400 syntax error ⇒ invalid_input surfacing openFDA's message; a 5xx ⇒ THROWS; a 200 non-JSON ⇒ schema_drift. The optional key rides ONLY the &api_key= query param — never logged or echoed.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| firm | No | Recalling firm name filter (→ recalling_firm), e.g. 'pfizer'. Matched as an escaped Lucene phrase. | |
| skip | No | Row offset for pagination (default 0). Page with _meta.pagination.nextOffset. | |
| limit | No | Max recall records to return (default 25, max 100). Offset-paginated via skip. | |
| state | No | 2-letter US state/territory postal code filter (→ state), e.g. 'CA'. Validated ^[A-Za-z]{2}$. | |
| reason | No | Reason-for-recall filter (→ reason_for_recall), e.g. 'contamination'. Matched as an escaped Lucene phrase. | |
| status | No | Recall status filter (→ status), e.g. 'Ongoing', 'Terminated', 'Completed'. | |
| product | No | Product description filter (→ product_description), e.g. 'insulin'. Matched as an escaped Lucene phrase. | |
| category | No | The recall category (default 'drug'): 'drug', 'device', or 'food'. Selects the openFDA /{category}/enforcement endpoint. | |
| classification | No | FDA recall classification filter: 'Class I' (most serious), 'Class II', or 'Class III'. |