# ToolMint openFDA Recalls

> FDA food, drug and device recall/enforcement lookups via openFDA — normalized, deduped, Class I/II/III explained. Not for clinical use.

- Status: Coming soon
- Price: $0.02 / call (x402 exact, USDC on Base eip155:8453, payTo 0xfbF7413bcB3a604936775C96FDbe0b0C9c9E37F5)
- Planned URL: https://toolmint-openfda-recalls-json.toolmint.workers.dev
- OpenAPI: https://toolmint.toolmint.workers.dev/tools/openfda-recalls-json/openapi.json

## Routes

- `GET /recalls` $0.02: Search food/drug/device recalls by product, firm, classification, date
- `GET /recalls/search` $0.02: Alias of /recalls
- `GET /recalls/food` $0.02: Food enforcement recalls only
- `GET /recalls/drug` $0.02: Drug enforcement recalls only
- `GET /recalls/device` $0.02: Device enforcement recalls only

## When to use it

- Check whether a product or company has FDA recall enforcement reports.
- List the latest ongoing Class I (most serious) recalls in food, drugs or devices.
- Get the class explained in plain words (`classificationGuide`).

Not for: adverse events (a different openFDA endpoint set, not covered), per-lot safety checks, or medical advice.

## Example

```bash
curl -i "https://toolmint-openfda-recalls-json.toolmint.workers.dev/recalls?productType=drug&classification=Class%20I&status=Ongoing&limit=5"
```

That hostname is the planned Worker name. The tool is **not deployed yet**.

Trimmed response (values illustrative):

```json
{
  "tool": "openfda-recalls-json",
  "version": "0.1.0",
  "count": 5,
  "byClassification": { "Class I": 5 },
  "classificationGuide": {
    "Class I": "Class I - most serious: reasonable probability of serious adverse health consequences or death.",
    "Class II": "...", "Class III": "..."
  },
  "recalls": [
    {
      "recallNumber": "...", "eventId": "...", "productType": "Drugs",
      "classification": "Class I",
      "classificationExplained": "Class I - most serious: ...",
      "status": "Ongoing", "recallingFirm": "...",
      "productDescription": "...", "reasonForRecall": "...",
      "codeInfo": "...", "distributionPattern": "...", "voluntaryMandated": "...",
      "recallInitiationDate": "20260101", "reportDate": "20260110",
      "city": "...", "state": "...", "country": "..."
    }
  ],
  "summary": { "headline": "5 recall(s): 5 Class I, 0 Class II, 0 Class III." },
  "query": { "productType": "drug", "classification": "Class I", "status": "Ongoing", "search": "...", "limit": 5, "skip": 0 },
  "provenance": {
    "source": "openFDA", "sourceUrl": "https://api.fda.gov/drug/enforcement.json?search=...",
    "sourceUrls": ["..."], "fetchedAt": "2026-10-31T12:00:00.000Z",
    "license": "CC0 1.0 Universal (US government work / public domain dedication)",
    "licenseUrl": "https://open.fda.gov/license/", "termsUrl": "https://open.fda.gov/terms/"
  },
  "fetchedAt": "2026-10-31T12:00:00.000Z",
  "disclaimer": "Do not rely on openFDA to make decisions regarding medical care. Results are unvalidated. Not for clinical use.",
  "clinicalUse": false,
  "cached": false
}
```

Results are de-duplicated and sorted Class I, then II, then III, then newest report date.

## Data source and licence

openFDA enforcement endpoints (`api.fda.gov/food|drug|device/enforcement.json`). CC0 1.0 (public domain dedication); see https://open.fda.gov/terms/. This is not an official FDA product.

## Freshness and caching

Full results may be cached in memory for 15 minutes (`cached: true`). Partial results and errors are not cached. openFDA itself updates its enforcement data on its own schedule; `fetchedAt` shows when we asked.

## Limits

- Max 50 results per call, `skip` up to 500.
- Search is a phrase/term match on product description and firm name, not fuzzy.
- Long text is cut (product description and reason 1200 chars).
