Everything that got pulled from shelves, both sides of the Atlantic
The Product Recall API returns FDA product-safety recalls as clean JSON.
10 active endpoints. Every call is 1 credit.
- POST/recall/v1/search
- POST/recall/v1/recall_detail
- POST/recall/v1/by_company
- POST/recall/v1/latest
- POST/recall/v1/batch
- POST/recall/v1/stats
- POST/recall/v1/categories
- +3 more
What Product Recall & Safety endpoints does ReefAPI ship?
10 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
Product Recall & Safety API
3 of 10 endpoints, ready to run
Recalls from the last N days, most recent first, with the hazard classification and a severity score on each.
{ "ok": true, "meta": { "api": "recall", "endpoint": "latest", "mode": "live", "latency_ms": 1185.3, "record_count": 10, "cache_hit": false }, "data": { "recalls": [ { "source": "openFDA", "category": "food", "recall_number": "H-1230-2026", "event_id": "99479", "status": "Ongoing", "classification": "Class I", "severity_score": 90, "recalling_firm": "MIDWEST POULTRY SERVC C/O H & LELECTRIC", "product_description": "Grade A White In-shell Chicken eggs packaged in the following configurations: 1. Kroger, Medium, 12 Eggs, Net Wt 21 oz (1lb 5oz) 596g, UPC 0 11110-60902 1. Distributed by The Kroger Co., Cincinnati, OH 45202. 2. Kroger, Medium, 30 Eggs, Net Wt 52.5 oz (3lb 4.5oz) 596g, UPC 0 11110-60980 9. Distributed by The Kroger Co., Cincinnati, OH 45202. 3. Kroger, Large 12 Eggs, Net Wt 24 oz (1lb 8oz) 681g, UPC 0 11110-60903 8. Distributed by The Kroger Co., Cincinnati, OH 45202. 4. Kroger, Large 18 Eggs, Net Wt 36 oz (2lb 4oz) 1.03kg, UPC 0 11110-60933 5. Distributed by The Kroger Co., Cincinnati, OH 45202. 5. Kroger, Large 60 Eggs, Net Wt 7lb 8oz (3.40kg), UPC 0 11110-60933 5. Distributed by The Kroger Co., Cincinnati, OH 45202. 6. Kroger, Extra Large 12 Eggs, Net Wt 27 oz (1lb 11oz) 766g, UPC 0 11110-60904 5. Distributed by The Kroger Co., Cincinnati, OH 45202. 7. Kroger, Jumbo 12 Eggs, Net Wt 30 oz (1lb 14oz) 851g, UPC 0 11110-60905 2. Distributed by The Kroger Co., Cincinnati, OH 45202. Packed by Tx Lic #613171, 800 Wabash Rd, N. Manchester, IN 46962. 8. Brookshire's farm fresh, Large 6 Eggs, Net Wt 12 oz (341g), UPC 0 92825-09564 4. Distributed by: Brookshire Grocery Company, P.O. Box 1411, Tyler, TX 75710-1411. 9. Brookshire's farm fresh, Large 12 Eggs, Net Wt 24 oz (1lb 8oz) 681g, UPC 0 92825-09555 2. Distributed by: Brookshire Grocery Company, P.O. Box 1411, Tyler, TX 75710-1411. 10. Brookshire's farm fresh, Large 18 Eggs, Net Wt 36 oz (2lb 4oz) 1.03kg, UPC 0 92825-09556 9. Distributed by: Brookshire Grocery Company, P.O. Box 1411, Tyler, TX 75710-1411. 11. Brookshire's farm fresh, Large 36 Total Eggs TWIN PACK (18 Each), Net Wt 36 oz (2lb 4oz) 1.03kg, UPC 0 92825-10980 8. Distributed by: Brookshire Grocery Company, P.O. Box 1411, Tyler, TX 75710-1411. 12. Super 1 Foods Large 60 Eggs, Net Wt 120 oz (7lbs8oz) 3.4kg, UPC 0 92825-09563 7. Distributed by: Brookshire Grocery Company, P.O. Box 1411, Tyler, TX 75710-1411. 13. Brookshire's farm fresh, Extra Large 18 Eggs, Net Wt 40.5 oz (2lb 8.5oz) 1.15kg, UPC 0 92825-09560 6. Distributed by: Brookshire Grocery Company, P.O. Box 1411, Tyler, TX 75710-1411. 14. Brookshire's farm fresh, Jumbo 12 Eggs, Net Wt 30 oz (1lb 14oz) 851g, UPC 0 92825-09558 3. Distributed by: Brookshire Grocery Company, P.O. Box 1411, Tyler, TX 75710-1411. Packed by MPS Egg Farms, 14374 E State Hwy 21, Byran, TX 77808. 15. Country Morning Medium 12 Eggs, Net Wt 21 oz (1lb 5oz) 596g, UPC 0 78566-00104 5. 16. Country Morning Large 12 Eggs, Net Wt 24 oz (1lb 8oz) 681g, UPC 0 78566-20000 4. 17. Country Morning Large 18 Eggs, Net Wt 36 oz (2lb 4oz) 1.03kg, UPC 0 78566-00503 6. 18. Country Morning Large 2 1/2 Dozen Eggs, UPC 0 79307-00516 2. 19. Country Morning Extra Large 12 Eggs, Net Wt 27 oz (1lb 11oz) 766g, UPC 0 78566-00102 1. 20. Country Morning Jumbo 12 Eggs, Net Wt 30 oz (1lb 14oz) 851g, UPC 0 78566-00101 4. 21. Cal-Maine Sunups 2 1/2 Dozen Eggs, UPC 0 28621-30498 7. Packed by Tx Lic #s. 0840962, 0840961 MPS Egg Farms, 2750 County Road 1011, Center, TX 75935. Bulk Product packaged as follows: 22. Medium Grade A JD 183, 15 dozen, MPS Egg Farms TX Lic. No. 0840961, 14374 E Hwy 21, Byran, TX 77808. 23. Medium Grade A JD 158, 30 dozen, MPS Egg Farms TX Lic. No. 0840961, 14374 E Hwy 21, Byran, TX 77808. 24. Large Grade A JD 193, 15 dozen, MPS Egg Farms TX Lic. No. 0840961, 14374 E Hwy 21, Byran, TX 77808. 25. Large Grade A JD 193, 30 dozen MPS Egg Farms TX Lic. No. 0840961, 14374 E Hwy 21, Byran, TX 77808. 26. Grade A Large Egg JD 208, 900 dozen, Distributed by MPS Egg Farms, 14374 E Hwy 21, Byran, TX 77808. 27. Extra Large Grade A, JD 193, 15 dozen, MPS Egg Farms TX Lic. No. 0840961, 14374 E Hwy 21, Byran, TX 77808. 28. Jumbo Grade A, JD 175, 16.67 Dozen, MPS Egg Farms TX Lic. No. 0840961, 14374 E Hwy 21, Byran, TX 77808. Keep Refrigerated at or Below 45-Degrees F.", "product_quantity": "1,589,577 dozen total", "reason_for_recall": "Possible Salmonella Enteritidis", "code_info": "Code information is printed on the left or right sides of the carton. Codes P-1950 or 0840962 with a Julian Date between 157 and 184 and a Best By/Sell By date Between July 20 - August 17, 2026", "product_type": "Food", "voluntary_mandated": "Voluntary: Firm initiated", "initial_firm_notification": "Two or more of the following: Email, Fax, Letter, Press Release, Telephone, Visit", "distribution_pattern": "Arkansas, Louisiana, Mississippi, New Mexico, Oklahoma, Texas", "city": "N Manchester", "state": "IN", "country": "United States", "recall_initiation_date": "20260722", "center_classification_date": "20260812", "report_date": "20260819", "termination_date": null, "more_code_info": "", "brand_name": null, "generic_name": null, "manufacturer_name": null, "product_ndc": null, "substance_name": null, "device_name": null, "medical_specialty_description": null, "openfda": null }, { "source": "openFDA", "category": "food", "recall_number": "H-1228-2026", "event_id": "99097", "status": "Ongoing", "classification": "Class I", "severity_score": 80, "recalling_firm": "Bazzini LLC", "product_description": "Dark Chocolate Coconut Almond Bites, 3.17oz, Plastic Pouches, 10 Packages per case.", "product_quantity": "1,382,916 Pieces", "reason_for_recall": "Undeclared peanuts", "code_info": "B15354, B15356, B15357, B15360, B15361, B15363", "product_type": "Food", "voluntary_mandated": "Voluntary: Firm initiated", "initial_firm_notification": "E-Mail", "distribution_pattern": "The product was distributed to WA.", "city": "Allentown", "state": "PA", "country": "United States", "recall_initiation_date": "20260523", "center_classification_date": "20260812", "report_date": "20260819", "termination_date": null, "more_code_info": "", "brand_name": null, "generic_name": null, "manufacturer_name": null, "product_ndc": null, "substance_name": null, "device_name": null, "medical_specialty_description": null, "openfda": null }, { "source": "openFDA", "category": "food", "recall_number": "", "event_id": "99453", "status": "Ongoing", "classification": "Not Yet Classified", "severity_score": 50, "recalling_firm": "Taylor Farms de Mexico S. de R.L. de C.V.", "product_description": "MARKON BLEND LETT/ROM 80/20 WITH SEP BAGGIES 4/5# Iceberg, Romaine, Carrots, Red Cabbage products.", "product_quantity": "855 cases", "reason_for_recall": "Potential Cyclospora contamination.", "code_info": "MARKON BLEND LETT/ROM 80/20 WITH SEP BAGGIES 4/5# TFMX183A05 7/21/2026 TFMX184A02 7/22/2026 TFMX187B02 7/25/2026 TFMX189A03 7/27/2026 TFMX190A03 7/28/2026 TFMX190B01 7/28/2026 TFMX191A02 7/29/2026 TFMX194B02 8/1/2026", "product_type": "Food", "voluntary_mandated": "Voluntary: Firm initiated", "initial_firm_notification": "Two or more of the following: Email, Fax, Letter, Press Release, Telephone, Visit", "distribution_pattern": "Domestic: AL, AR, CT, FL, GA, IA, IL, IN, KS, KY, LA, MA, MD, MI, MO, MS, NC, NH, NJ, OH, OK, PA, SC, TN, TX, VA, and WI Foreign: Mexico.", "city": "Doctor Mora", "state": "", "country": "Mexico", "recall_initiation_date": "20260717", "center_classification_date": null, "report_date": "20260819", "termination_date": null, "more_code_info": "", "brand_name": null, "generic_name": null, "manufacturer_name": null, "product_ndc": null, "substance_name": null, "device_name": null, "medical_specialty_description": null, "openfda": null } ], "categories_searched": [ "food" ], "total": 43, "skip": 0, "limit": 10, "has_more": true, "next_skip": 10, "window_days": 30 } }
How the Product Recall & Safety API works
Product Recall & Safety is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.
No OAuth app, no request signing, no per-site account. One key covers all 184 engines.
Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.
Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.
One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.
Watching your own catalogue for a recall you did not hear about
Recalls are announced by the regulator, not by your supplier. The gap between the two is the window in which you are still selling it.
{"category": "food", "days": 7, "classification": "Class I"}The daily sweep. Class I is the level that means a reasonable probability of serious harm, so it is the one worth waking someone up for.
{"company": "Acme Foods"}For each supplier on your list. Matching on the recalling firm is more reliable than matching on product text.
Each row carries the classification, a severity score, the reason, the quantity affected and where it was distributed — enough to decide whether it touches you without opening the regulator's site.
curl -X POST https://api.reefapi.com/recall/v1/latest \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"days":120,"limit":3}'{
"ok": true,
"data": { … },
"meta": {
"api": "recall",
"endpoint": "latest",
"mode": "live",
"latency_ms": …,
"record_count": …
},
"error": null
}Recall number prefixes, hazard classes and the severity score
The recall_number prefix, not a category field, is what tells you which FDA registry a row came from, and recall_detail auto-detects the category from it. The hazard class and the derived severity_score are two different things, and the score is ours rather than the FDA's. Everything below was read off live responses in August 2026.
| Value | What it means | Measured |
|---|---|---|
| H-… | Food and cosmetics recall. This is the prefix most current food recalls actually carry, not F | H-1034-2026, Albertsons peanut butter bar, Class II; 15 of 50 rows in a 30-day latest sweep |
| F-… | Also food, from the older enforcement numbering. recall_detail still resolves it to category food | F-1397-2012 returned meta.category food without passing category |
| D-… | Human and animal drug recall | D-0590-2025, PFIZER INC, Class II, Ongoing |
| Z-… | Medical device recall | 17 of 50 rows in the same 30-day latest sweep |
| Class I / II / III | FDA hazard tier, I being the most serious | food stats: 12,867 Class I, 14,704 Class II, 1,745 Class III |
| Not Yet Classified | A fourth classification value the parameter enum does not list, used while the FDA has not tiered the recall yet | 2 of 50 rows in the 30-day sweep; 1 row in the all-time food classification stats |
| severity_score | A derived 0-100 number built from hazard class plus lifecycle status. It is not an FDA field | Class I ongoing 80-100, Class I terminated 70, Class II 55-75, Class III 45, Not Yet Classified 50-60 |
| Date fields | Plain YYYYMMDD strings with no separators, and null when the event has not happened | report_date 20260610, termination_date 20260702 on a terminated recall and null on an ongoing one |
status accepts Ongoing, Completed, Terminated and Pending and is declared on_invalid=ignore, so a typo silently returns unfiltered results instead of an error. classification and category are on_invalid=reject and fail loudly instead.
Two regulators, two shapes, one endpoint
Measured against both feeds, on recent windows and on a pathogen search.
The US feed covers food, drugs and devices with the regulator's own recall numbers and event ids. The European feed covers consumer goods — toys, jewellery, electricals — with case numbers, risk types and a link to the official alert. Every row names its source, so you never have to guess which regime a record came from.
Alongside the regulator's own hazard class, each row carries a numeric severity score. A class is a label you have to know how to read; a score is something you can threshold, sort and alert on without encoding the regulator's vocabulary into your own system.
Recalling firm, product description with pack sizes and UPCs, the reason, the quantity affected, the distribution area and the status — ongoing, completed or terminated. Status matters most: an ongoing recall is an operational problem and a terminated one is a historical fact, and they look identical in a headline.
A pathogen search returned thousands of historical matches across the archive. That is the honest behaviour of a full-text search over decades of filings — narrow it with the date and status filters rather than expecting the query alone to mean 'recent and relevant'.
A US row and an EU row do not carry the same fields, because the regulators do not publish the same things — one leads with a recall classification, the other with a risk type and a product category. We keep both shapes rather than flattening them to their intersection, which would throw away most of what makes each useful. It does mean handling two shapes on your side.
What people build with Product Recall & Safety
The jobs this data is most often used for.
endpoints
credit per call
Marketplaces call by_company to flag products from a brand with active recalls.
Compliance teams monitor latest recalls for their categories.
Consumer apps use search and recall_detail to warn users.
What Product Recall & Safety data costs
The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.
Full pricing →- 1,000 free credits on signup, no card
- One key, all 184 APIs, one credit pool
- Failed and blocked calls are never charged
- Credits roll over and never expire
Call it in two lines
Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.
curl -X POST https://api.reefapi.com/recall/v1/latest \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"days":120,"limit":3}'import requests
r = requests.post(
"https://api.reefapi.com/recall/v1/latest",
headers={"x-api-key": REEF_KEY},
json={
"days": 120,
"limit": 3
},
)
print(r.json()["data"])Have a question? We got answers.
The questions people actually ask before wiring up Product Recall & Safety.
Get a free key →Why does my food recall number start with H when the docs say F means food?▾
Both prefixes are food. F belongs to the older enforcement numbering and H is what current food recalls carry: in a 30-day latest sweep all 15 food rows were H-something, for example H-1034-2026 from Albertsons. You do not have to work it out yourself. recall_detail auto-detects the category from the prefix, and passing only recall_number H-1034-2026 came back with meta.category food.
Does this cover vehicle, CPSC or EU recalls?▾
Not in the search results. Every row measured across search, latest and by_company carried source openFDA, covering the FDA food, drug and device registries only. The categories action does return EU Safety Gate reference vocabulary, 34 product-category keys, 22 risk types and a 251-entry country list, but no EU rows came back from the data actions. NHTSA vehicle recalls are a separate engine.
Is severity_score an FDA number?▾
No. The FDA publishes a hazard class, not a score. severity_score is derived from that class plus the recall's lifecycle status, which is why one class spans a range: ongoing Class I recalls measured 80, 90 and 100 while a terminated Class I, F-1397-2012, scored 70. Class II ran 55 to 75 and Class III 45. Set include_severity to false if you want the record without it.
Why did stats ignore my category=all?▾
stats aggregates one registry at a time. A call with field classification and category all came back with meta.category food and food-only buckets. To get cross-category totals, run stats once per category and add them up. The same call with category drug returned its own buckets: 14,801 Terminated, 2,662 Ongoing and 436 Completed.
Which fields come back null on a normal record?▾
The drug and device specific fields are null on food rows and the other way round. On measured food records brand_name, generic_name, manufacturer_name, product_ndc, substance_name, device_name and openfda were all null, while product_description, reason_for_recall, recalling_firm, city, state and the dates were populated. termination_date is null for anything still Ongoing. Check the field you need, not whether a record came back.
How do I page past the first 20 results?▾
Every list response carries total, has_more and next_skip, and you feed next_skip back in as skip. limit tops out at 100 per page and the underlying ceiling is skip plus limit at most 25,000, so roughly 25,000 records per filter combination. A search for peanut butter in food reported total 680 with limit 3 and next_skip 3.
What does latest with category=all actually return?▾
It fans out across all three registries and merges them, so a limit of 50 is not 50 rows from one place. A measured 30-day window returned 16 food, 17 drug and 17 device rows, with meta.categories_searched listing all three and total 328. Ordering is newest report_date first, and the window is set by days, which defaults to 90 and caps at 3,650.
Can I watch a list of products in one request?▾
Yes. batch takes up to 20 keyword queries and returns a separate {query, count, recalls[]} block for each, which is the compliance-watch shape. If you already know the firm, by_company is more precise: it matches the FDA recalling_firm field case-insensitively on partial words, which is why a Pfizer query returned rows filed under both PFIZER INC and Pfizer, 155 in total in the drug registry.
What is the Product Recall & Safety API?▾
Product Recall & Safety API is a ReefAPI endpoint group for product recall & safety It returns live JSON through POST requests under /recall/v1.
Is the Product Recall & Safety API free to try?▾
Yes. ReefAPI starts with 1,000 free credits, no card required. Product Recall & Safety calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Product Recall & Safety login or account?▾
No login to Product Recall & Safety is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Product Recall & Safety data?▾
The page example is captured from a live search call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Product Recall & Safety API use?▾
Product Recall & Safety actions currently cost 1 credit per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Product Recall & Safety from an AI assistant or MCP client?▾
Yes. Connect ReefAPI once through MCP and your assistant can call recall actions with the same key, credit pool and JSON envelope used by normal REST requests.
19 Utilities & AI APIs on the same key
One key, one credit pool, one response envelope. If you are pulling Product Recall & Safety, you are one call away from the rest of the category — no second contract, no second integration.
Need something this API does not do?
Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.
Try it on your own data before you pay anything
The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 183 APIs, and the same envelope everywhere.
Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-08-30.