The recall watcher: about ninety alerts a week, and the one that names your shelf
The official alert lists land in a mailbox nobody reads, get matched against what you actually stock, and what reaches your phone is a pull-list and the customers who bought it - not another digest to skim
Setup: A weekend (~6-14 h)Running cost: $0-12/mo(software included)what it costs to run ↓Time saved: none directly— on a normal week this saves nothing, because the alternative is not doing it; the case is Article 12 of the GPSR, which since 13/12/2024 obliges a distributor who has reason to believe a product it sold is dangerous to act, and an alert published under the brand and model you stocked is exactly that reasonAfter setup: You run it— the feeds and the matching run unattended every day; the owner only appears when something is flagged, which on most weeks is neverData lives: Your server— Your stock list, your sales lookups and the alert register stay on your own server, and the screening model runs locally so no product list is sent anywhere. The only traffic leaving the building is fetching public alert data from the Commission, CPSC and openFDA.
Built for small businesses in general — not a sector list.
Before you start
A current list of what you stock - brand, product name, model, barcode where you have it, and the supplier it came from. This is the weekend, and without it there is nothing to match against
A dedicated mailbox that nobody reads, subscribed to the official Safety Gate weekly alert email and filtered to your product categories
Sales records you can query by product and date range, so a hit can produce a customer list rather than a guess
A machine that stays switched on - a small VPS runs the watcher, but not a language model, so the optional screening step needs an office machine or gets dropped
A named person who reads the flagged alert and decides. Nothing here contacts a customer or an authority by itself
What breaks firstFAILS SILENTLY
the Safety Gate subscription quietly stops arriving - the address bounces once, a filter reclassifies it, or the subscription lapses - and the watcher keeps running happily against an empty mailbox. Silence is the normal output of this system, so a broken feed looks exactly like a good week. Add a staleness check that alerts you when no alert of any kind has been ingested for eight days, and make that check the one thing you never switch off.
Version history
v1.0 · 2026-08-27 — First release. Volume figures from the European Commission's Safety Gate annual report for 2025: 4,671 alerts (highest since 2003, +13% on 2024, more than double 2022), close to 100 notifications a week, 5,794 follow-up actions, cosmetics 36% / toys 16% / electrical appliances 11%, chemical risk 53%, BMHCA 1,278 notifications and TPO 60 since its September 2025 ban - corroborated across three independent write-ups of the same report. GPSR obligations read off Regulation (EU) 2023/988 as published: Article 12 distributor duties (inform the manufacturer or importer, ensure corrective measures including withdrawal or recall, notify authorities via the Safety Business Gateway), Article 35(1) direct notification of every identifiable affected consumer using personal data already held, Article 35(2) safety-only contact details, Article 35(4) other channels, Article 36 plus Implementing Regulation (EU) 2024/1435 for the notice template and the prohibited softening wording, Article 37 choice of at least two remedies free of charge with a refund of at least the price paid. The one-in-three figure for consumers who keep using a recalled product after seeing the notice is the Commission's own stated rationale for the Article 36 rules. Architecture decision worth recording: Safety Gate publishes no documented public API and no RSS, so the input is the official weekly email subscription (filterable by category, notifying country and country of origin) rather than the portal's internal endpoint, which is an Angular app owing nobody stability. US feeds verified live on 27/08/2026 - the CPSC Recalls API at saferproducts.gov/RestWebServices/Recall returned JSON with no key, and openFDA food/enforcement.json returned 43 August-dated food enforcement reports, the first of which (H-1219-2026) was initiated 04/06/2026 and reported 12/08/2026, a 69-day lag that is written into the pitfalls as the reason openFDA is a backstop and not an alarm. RASFF Window is excluded on the Commission's own statement that its notifications do not reveal brands or business operators, which makes brand matching impossible. Deliberate design lines: nothing is ever sent to a customer or an authority automatically, the local model ranks rather than decides and is tuned to over-flag because a false negative is the hazard, the notice export fails on prohibited wording rather than warning about it, and every dismissed alert is stored with its reason because the register is the evidence, not the alert.
The EU published 4,671 dangerous-product alerts in 2025, about ninety a week, and almost none of them are yours. The job is not reading them. The job is the filter that says "this one names something on your shelf", and the lookup that says "and these eleven people bought it".
The architecture
the same flow as text
THE FEEDS — official, and deliberately boring
[ Safety Gate weekly email ] → dedicated mailbox (filtered to your categories at source)
[ CPSC Recalls API ] → saferproducts.gov/RestWebServices/Recall (US, no key)
[ openFDA enforcement ] → api.fda.gov/food/enforcement.json (US, backstop only)
▼
[ n8n — the sorter ] IMAP trigger + daily schedule
├─ 1. exact match: barcode / GTIN, when the alert carries one
├─ 2. exact match: brand, model, supplier — against NocoDB "what we stock"
└─ 3. the rest → Ollama: "could this be one of ours?" ranks, never decides
▼
├─ no hit → one row in the register, and silence. This is the normal week.
└─ possible hit → ntfy on your phone, with the alert and the reason
THE HIT — a handful of times a year, if that
[ you confirm it is yours ]
├─ pull-list: where it is, how many, which batch codes
├─ customer list: query sales for that product and date range
├─ notice: 2024/1435 template → Gotenberg → PDF, banned-word check first
└─ register row: what you found, when, what you did, who you told
▼
[ you ] send the notice, inform the supplier, notify through the Safety Business Gateway. Nothing is sent to a customer or an authority automatically.
The load-bearing decision is the first line. Safety Gate has no documented public API and no RSS feed, but it does have an official weekly email subscription that you can filter by product category, notifying country and country of origin. So the automation subscribes a dedicated mailbox and parses email. That sounds like the crude option and it is the durable one: the portal is an Angular app over an internal endpoint that owes you nothing, while the subscription is a service the Commission runs on purpose. Scrape the portal and you are one redeploy away from a watcher that silently stops watching.
The second decision is that the "what we stock" table is the actual product. Everything else here is plumbing you could rebuild in a day. A current list of brands, models, barcodes and suppliers is the thing that takes a weekend and then takes ten minutes a month forever, and without it there is nothing to match against.
The problem
Start with the volume, because it is the whole reason nobody does this by hand. The Commission's Safety Gate report for 2025 recorded 4,671 alerts — the highest since the system started in 2003, up 13% on 2024 and more than double 2022, running at close to 100 notifications a week. National authorities took 5,794 follow-up actions on top. Cosmetics were the most-notified category at 36%, then toys at 16% and electrical appliances at 11%. Chemical risk drove 53% of all alerts, including 1,278 notifications for the fragrance BMHCA and 60 for TPO in nail polish since it was banned in September 2025.
Read those three categories again if you run a salon, a gift shop or an electrical installation business. This is not an importer's problem. Cosmetics on a salon shelf, a toy on a counter display, a charger fitted last spring — that is where a third of the alerts land.
And since 13 December 2024 the obligation is explicit. Under Article 12 of the GPSR (Regulation (EU) 2023/988), a distributor — which is what a shop that buys from a wholesaler is — who has reason to believe a product it has made available is dangerous must immediately inform the manufacturer or importer, ensure corrective measures are taken including withdrawal or recall, and inform the market surveillance authorities through the Safety Business Gateway. "Reason to believe" is doing a lot of work in that sentence. An alert was published. It named the brand and the model. Nobody in your shop read it.
Then Article 35 turns the sales record into a legal instrument. In a recall you must directly notify every affected consumer you can identify, without undue delay, using the personal data you already hold. Not a website banner. Not a post. If you have their email because they bought it, you owe them an email. Article 35(2) goes further and says you must offer customers the option to register contact details used for safety purposes only. Article 35(4) covers the rest with website, social, newsletter, in-store and media notices.
Article 36 then tells you how to write it, and Implementing Regulation (EU) 2024/1435 gives the template that has applied since the same December date. The notice must be in plain language and must not use wording that softens the risk — "voluntary", "precautionary", "discretionary", "in rare situations", or any statement that no accidents have been reported. Article 37 prices it: the consumer gets a choice of at least two of repair, replacement or a refund of at least the price paid, free of charge, offered proactively, with no time limit for claiming. The EU's own rationale for all of this is blunt — roughly one in three consumers keeps using a recalled product after seeing the notice, because the notice was written to be survivable rather than clear.
So the shape of the work is: watch about ninety alerts a week, throw away eighty-nine, and on the ninetieth produce a shelf action, a customer list and a compliant notice. That is a filter and a database query. It is not a subscription.
Tool choices — and why
n8n
(Sustainable Use License, free for internal business use, 202k stars, last commit 27/08/2026) does the fetching, the matching and the alerting. It has an IMAP trigger for the Safety Gate mail, HTTP nodes for the two US APIs, and a schedule that will retry when a feed is down. If you already run it for another blueprint here, this is one more workflow, not one more machine.
NocoDB
(Sustainable Use License since 29/01/2026, free for internal business use, 65k stars, last commit 27/08/2026) holds two tables: what you stock, and the alert register. Spreadsheet-shaped is right because a shop owner has to maintain the first one by hand and read the second one under pressure. Baserow (5.6k stars, actively developed) is the swap if you prefer its licence.
Ollama
(MIT, 180k stars, last commit 22/08/2026) runs the screening model locally for the alerts that did not match exactly — "SUNTECH beach umbrella, model BX-40, plastic pole" against a stock list that says "Suntec parasol 2m". A small model is fine here because the question is a similarity judgement, not a legal one. It costs nothing per alert and no product list leaves your building. This step is optional: drop it and you still have a working exact-match watcher, you just read a few more borderline alerts yourself.
ntfy
(Apache-2.0, 30.5k stars, pushed 30/05/2026) puts the hit on your phone. Email is the wrong channel for this because the whole failure mode is a message that gets skimmed and archived, and you already have a mailbox filling up with weekly alert digests.
Gotenberg
(MIT, last commit 21/08/2026) turns the filled template into the PDF you hand to customers and attach to the register. Docker runs all of it on one box.
Monthly cost
Software: €0, every piece. Feeds: €0 — Safety Gate's subscription is free, CPSC's Recalls API needs no key, and openFDA is free keyless at 240 requests a minute and 1,000 a day per IP address, or 120,000 a day with a free key. Hosting: nothing new if you already run an automation box, otherwise roughly €5–12/month for a small VPS. One honest caveat on that number: a €5 VPS will not run a language model usefully. Either run Ollama on an office machine that is already switched on, or skip the model step. Commercial recall-monitoring services start in the hundreds per month and are sold to compliance teams, not to shops with four hundred product lines.
Setup outline
1. Build the stock list first, before any automation. Brand, product name, model, barcode where you have it, supplier, and the categories you actually sell. Four hundred rows is a Saturday. Without this the rest is decoration.
2. Create a dedicated mailbox — alerts@ — that nobody reads. It exists to be parsed.
3. Subscribe it on the Safety Gate portal and use the filters: your product categories, and country of origin if that narrows things honestly. Confirm the activation link. Wait a week and check the first mail actually arrived before building anything on top of it.
4. Add the national feed for your own country. Every member state publishes its own recall page, and it lands earlier and in your language.
5. Wire the IMAP trigger in n8n, parse the mail into one record per alert — case number, product, brand, model, barcode, category, risk, measures, notifying country — and store every one of them, matched or not. The register is the point.
6. Add the US feeds if you sell there: GET saferproducts.gov/RestWebServices/Recall?format=json&RecallDateStart=… daily, and openFDA if you handle food.
7. Match in that order: barcode, then brand plus model, then supplier name. Normalise both sides first — case, punctuation, accents, and the spaces people put in model numbers.
8. Send the leftovers to the local model with the stock list in the prompt, and ask for a score and one sentence of reasoning. Store the reasoning. You will want to know why it flagged something at 2am six months from now.
9. Alert to ntfy with the case number, the product, the risk and the reason. One message, not a digest.
10. Build the response side only once the watching side has run quietly for a month: the sales query, the 2024/1435 notice template with the banned-word check, and the register fields for what you did and who you told.
11. Test it against a real past alert. Pick something you genuinely stocked last year from the Safety Gate archive, feed it in, and see whether your own filter catches it.
Pitfalls — the real ones
The alert names the manufacturer, and you know the wholesaler
This is the failure that matters. Safety Gate records the brand and model as the notifying authority found them, which is often a factory brand you have never typed into anything. Barcode is the only reliable key, and it is only sometimes present — CPSC's own field list says UPC is included "when provided in a recall". So keep the supplier against every stock line as a third matching key, and accept that this filter is tuned to over-flag. A false alarm costs you two minutes. The other kind of miss is the one that ends up in front of a market surveillance authority.
openFDA enforcement is an archive, not an alarm
Checked live on 27/08/2026, the endpoint held 43 food enforcement reports with an August report date, and the first one was recall H-1219-2026: initiated 4 June 2026, reported 12 August 2026. That is 69 days. The dataset's own last_updated was 19 August. It is a good backstop and a useless siren, so treat the FDA and CPSC press pages as the fast signal and the API as the record.
RASFF will not do what you want for food
The RASFF Window is public, but the Commission states plainly that its notifications "do not reveal commercial details such as brands and business operators". You cannot brand-match against it. For food the usable routes are the RASFF consumers' portal, which carries actual recall notices, and your national food authority. Build the food watcher on those, and do not pretend the EU has one clean food feed, because it does not.
The model must never be the last word
It ranks, you decide. Ask it for a score and a reason, show both, and make confirming a hit a deliberate tap. And tune it towards noise: in this workflow a false positive is an inconvenience and a false negative is the actual hazard.
An LLM will write a notice that breaks Article 36 on the first try
"We are issuing a voluntary precautionary recall. No incidents have been reported." Every clause in that sentence is prohibited wording. Run a literal banned-word check over the draft before it can be exported — voluntary, precautionary, discretionary, "in rare cases", "no accidents reported" — and fail the export rather than warning about it.
You are about to use the customer database for something the customer never asked for, and that is the correct behaviour here
Article 35(1) requires you to use the personal data you hold to notify affected consumers. What it does not do is licence a marketing send. Keep the safety contact list separate, write down that its purpose is recall notification, and offer the safety-only contact option Article 35(2) asks for rather than bolting a consent checkbox onto your newsletter.
The register is the deliverable, not the alert
The Commission's business guidelines ask you to keep an internal register of consumer complaints, recalls and corrective measures. Store every alert you screened, including the thousands you dismissed, with the reason. "We check the EU alerts weekly" is a claim. A table with 4,671 rows and a decision on each is evidence.
This is not the expiry tracker and it is not the goods-in check
Those watch your own dates and your own deliveries. This one watches what the rest of the market found out about a product you already sold.
Verified repos
n8n — Sustainable Use License (free self-hosted internal use), 202k stars, last commit 27/08/2026 NocoDB — Sustainable Use License since 29/01/2026 (free for internal business use), 65k stars, last commit 27/08/2026 Baserow — open-source core with a paid edition, 5.6k stars, actively developed — alternative to NocoDB Ollama — MIT, 180k stars, last commit 22/08/2026 ntfy — Apache-2.0, 30.5k stars, pushed 30/05/2026 Gotenberg — MIT, last commit 21/08/2026
Get the next blueprint as it publishes — free, practical, verified tooling only.
Subscribe · Want this audited or extended for your business? DM @RXed_EU
What this costs to run
Priced as Classify & route — one email or ticket including a short quoted thread; output is a label plus a one-line reason. the model only sorts the alerts that did not match on barcode or brand into probably-ours and probably-not, with one sentence of reasoning; the deterministic match does the real work and the owner makes every decision.
Adjust the volume to yours; the bill is a range because the assumptions are ranges.