ProductGuru
Look up a product by EAN or UPC barcode: name, brand, category, specs and any official government recall notice. Remote, no API key.
Máy chủ MCP được lưu trữ
npx add-mcp 'https://myproduct.guru/mcp'Cài vào Claude Code, Codex, Cursor và nhiều công cụ khác
Tài liệu
ProductGuru · Recalls · Data · Developers
Recall API & feeds
A free, open, read-only API over consumer-product recall notices compiled from 32 public regulatory authorities worldwide. No key. No account. No write endpoints. Every record names the authority that issued it and links to that authority’s own notice.
The one call that matters
curl -s "https://myproduct.guru/api/v1/recalls/3109850018511"
Is this barcode recalled anywhere in the world?
At a glance
| Base URL | https://myproduct.guru/api/v1 |
|---|---|
| Auth | None. No key, no registration, no tiers. |
| Methods | GET and HEAD only. There are no write endpoints. |
| Format | JSON (UTF-8). CORS Access-Control-Allow-Origin: * — call it straight from the browser. |
| Rate limit | 60 requests/minute per IP, burst 20. Over the limit you get 429 with Retry-After. |
| Caching | Every response carries ETag and Last-Modified. Send If-None-Match, get 304. |
| Licence | CC-BY-4.0 — header X-Data-License: CC-BY-4.0 |
| Cite as | ProductGuru consumer recall dataset (https://myproduct.guru), CC BY 4.0, DOI 10.5281/zenodo.22685727 — 10.5281/zenodo.22685727 |
| OpenAPI | /api/v1/openapi.json |
authority vs issuing_body. authority is the register a notice was compiled from; issuing_body is the government body that actually issued it. For most registers these are the same. They differ for shared portals — canada-recall-portal carries Transport Canada, the Canadian Food Inspection Agency and several Health Canada branches side by side, so we resolve the issuer per notice rather than crediting one regulator for all of them. Where the portal does not say, issuing_body names the portal itself; we never guess a regulator.
Endpoints
GET /api/v1/recalls/{ean} — one barcode
The core call. Pass an EAN/GTIN of 8–14 digits. Returns every notice on file for that barcode, newest first.
curl -s "https://myproduct.guru/api/v1/recalls/3109850018511"
{
"meta": { "license": "CC-BY-4.0", "doi": "10.5281/zenodo.22685727", ... },
"ean": "3109850018511",
"recalled": true,
"count": 1,
"recalls": [
{
"authority": "rappelconso-france",
"authority_name": "RappelConso — Government of France",
"authority_url": "https://rappel.conso.gouv.fr/",
"notice_id": "2024-05-0123",
"notice_url": "https://rappel.conso.gouv.fr/fiche-rappel/.../interne",
"published_date": "2024-05-14",
"first_indexed_at": "2024-05-15T03:12:44Z",
"country": "FR",
"country_name": "France",
"risk_level": null,
"authority_classification": "volontaire (sans arrêté préfectoral)",
"hazard": "… the authority's own hazard wording …",
"product_name": "antesite reglisse anis",
"product_category": "Food",
"ean": "3109850018511",
"productguru_url": "https://myproduct.guru/wiki/recall/…"
}
]
}
"recalled": false with "count": 0 is a normal 200 — a barcode with no notice on file is an answer, not an error. A string that is not 8–14 digits is a 400.
GET /api/v1/recalls — paged listing
Filter by date, country, authority, category or brand. Newest first.
curl -s "https://myproduct.guru/api/v1/recalls?since=2026-08-01&country=FR&limit=5"
Everything the EU Safety Gate recalled in the Toys category.
curl -s "https://myproduct.guru/api/v1/recalls?authority=eu-safety-gate&category=Toys&limit=50"
Polling for new data? Sort by indexed and filter on updated_since — that is when we first saw the notice, so nothing slips past you when an authority backdates one.
curl -s "https://myproduct.guru/api/v1/recalls?updated_since=2026-09-01&sort=indexed&limit=100"
| Parameter | Meaning |
|---|---|
since, until | YYYY-MM-DD. Filters the authority’s publication date. |
updated_since | YYYY-MM-DD. Filters when ProductGuru first indexed the notice. |
country | ISO 3166-1 alpha-2, e.g. FR. See /countries. |
authority | Slug from /authorities, e.g. us-cpsc. |
category, brand | Exact match, case-insensitive. |
sort | published (default) or indexed. |
limit | 1–100, default 20. |
offset | 0–10,000. Past that, narrow the window with since / until — deep offsets are slow for everyone. |
The response’s meta.next is the ready-made URL for the following page, or null at the end.
GET /api/v1/recalls/stats — dataset shape
Totals by authority, by year and by country, plus when the dataset was last added to. Cached for an hour.
curl -s "https://myproduct.guru/api/v1/recalls/stats"
GET /api/v1/authorities — who we compile from
Slug, official name, homepage and current notice count for every register.
curl -s "https://myproduct.guru/api/v1/authorities"
GET /api/v1/countries
Every ISO 3166-1 alpha-2 code present in the data, with counts.
curl -s "https://myproduct.guru/api/v1/countries"
Feeds
Newly indexed notices, as they land. Both feeds accept the same ?authority=, ?country= and ?limit= filters as the listing endpoint.
Subscribe in any reader, or wire it into Slack, Zapier or an alerting job.
curl -s "https://myproduct.guru/recalls.xml" # RSS 2.0
curl -s "https://myproduct.guru/recalls.atom" # Atom 1.0
curl -s "https://myproduct.guru/recalls.xml?country=DE&limit=25" # filtered
A worked example
Python, standard library only — no SDK, no key.
import urllib.request, json
url = "https://myproduct.guru/api/v1/recalls/3109850018511"
with urllib.request.urlopen(url) as r:
data = json.load(r)
print(data["recalled"], data["count"])
for rec in data["recalls"]:
print(rec["authority_name"], "-", rec["hazard"][:80])
print(" official notice:", rec["notice_url"])
For AI assistants: MCP server
The same product facts are available to AI assistants over the Model Context Protocol. It is a remote server: nothing to install, no key, no account.
| Endpoint | https://myproduct.guru/mcp (Streamable HTTP) |
|---|---|
| Tool | product_lookup(ean) — one EAN-13, EAN-8 or 12-digit UPC-A per call, check digit validated. Read-only. |
| Returns | Name, brand/maker, category and recorded attributes as shown on /p/<barcode>, any government recall notices (agency, date, link to the agency’s notice), and the page URL to cite. No prices, offers, images or reviews; medicines are not covered. There is no search or listing tool. |
| Fair use | 20 lookups a minute and 200 a day per client. The 21st lookup inside a minute pauses that client until the next full hour (UTC). Walking sequential barcodes is blocked for the day. |
| Registry | Official MCP Registry: guru.myproduct/product-lookup |
Add it to any MCP client that supports remote servers, for example:
{
"mcpServers": {
"productguru": {
"type": "http",
"url": "https://myproduct.guru/mcp"
}
}
}
A not found answer means ProductGuru has no published page for that barcode; it says nothing about recalls. A found product with no linked notice is not a safety guarantee — the agency’s own register is the source of record.
Caching and etiquette
Send back the ETag you were given and unchanged pages cost you nothing.
ETAG=$(curl -sI "https://myproduct.guru/api/v1/recalls?limit=5" \
| awk -F": " 'tolower($1)=="etag"{print $2}' | tr -d "\r")
curl -s -o /dev/null -w '%{http_code}\n' \
-H "If-None-Match: $ETAG" "https://myproduct.guru/api/v1/recalls?limit=5"
# 304
- Stay under 60 requests/minute per IP. Bulk consumers: poll
updated_sinceonce a day rather than crawling every page. - Every response is
public-cacheable. Please honourmax-age. - Want the whole corpus at once instead? Take the open dataset and cite the DOI.
Attribution
The data is licensed CC-BY-4.0. Use it commercially, remix it, ship it in an app — just say where it came from:
ProductGuru consumer recall dataset (https://myproduct.guru), CC BY 4.0, DOI 10.5281/zenodo.22685727
ProductGuru is the compiler, not the issuing body. Every record carries authority_name and notice_url pointing at the register that actually issued it. When something matters, verify it there. This API is informational only and is not legal, medical or safety advice.
Registers we compile
| Slug | Authority | Jurisdiction |
|---|---|---|
accc-australia | Australian Competition and Consumer Commission | AU |
bvl-germany | Bundesamt für Verbraucherschutz und Lebensmittelsicherheit (Germany) | DE |
eu-safety-gate | European Commission — Safety Gate (RAPEX) | EU |
fsai-ireland | Food Safety Authority of Ireland | IE |
fsanz-australia-nz | Food Standards Australia New Zealand | AU |
canada-recall-portal | Government of Canada — recall portal (recalls-rappels.canada.ca) | CA |
gis-poland | Główny Inspektorat Sanitarny (Poland) | PL |
oecd-globalrecalls-bn | OECD GlobalRecalls — Brunei Darussalam | BN |
oecd-globalrecalls-tw | OECD GlobalRecalls — Chinese Taipei | TW |
oecd-globalrecalls-co | OECD GlobalRecalls — Colombia | CO |
oecd-globalrecalls-cr | OECD GlobalRecalls — Costa Rica | CR |
oecd-globalrecalls-id | OECD GlobalRecalls — Indonesia | ID |
oecd-globalrecalls-il | OECD GlobalRecalls — Israel | IL |
oecd-globalrecalls-jp | OECD GlobalRecalls — Japan | JP |
oecd-globalrecalls-kr | OECD GlobalRecalls — Korea | KR |
oecd-globalrecalls-my | OECD GlobalRecalls — Malaysia | MY |
oecd-globalrecalls-ph | OECD GlobalRecalls — Philippines | PH |
oecd-globalrecalls-sg | OECD GlobalRecalls — Singapore | SG |
oecd-globalrecalls-th | OECD GlobalRecalls — Thailand | TH |
oecd-globalrecalls-ae | OECD GlobalRecalls — United Arab Emirates | AE |
oecd-globalrecalls-vn | OECD GlobalRecalls — Viet Nam | VN |
rappelconso-france | RappelConso — Government of France | FR |
senacon-brazil | Senacon — Secretaria Nacional do Consumidor (Brazil) | BR |
transport-canada | Transport Canada — Vehicle Recalls Database | CA |
us-cpsc | U.S. Consumer Product Safety Commission | US |
us-usda-fsis | U.S. Department of Agriculture — Food Safety and Inspection Service | US |
us-fda-food | U.S. Food and Drug Administration — Food Enforcement | US |
us-fda-devices | U.S. Food and Drug Administration — Medical Devices | US |
us-nhtsa | U.S. National Highway Traffic Safety Administration | US |
uk-dvsa | UK Driver and Vehicle Standards Agency | GB |
uk-fsa | UK Food Standards Agency | GB |
uk-opss | UK Office for Product Safety and Standards | GB |