EU Product Recall Compliance Matcher (Safety Gate)
Pricing
from $3.00 / 1,000 item auditeds
EU Product Recall Compliance Matcher (Safety Gate)
Audit products by brand, model, EAN or CAS/EC number against official EU Safety Gate recall alerts, or stream the latest alerts with delta tracking. Returns alert details, match type and confidence. SVHC matching needs your own ECHA export.
Pricing
from $3.00 / 1,000 item auditeds
Rating
0.0
(0)
Developer
goober
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
EU Safety Gate recall checker: audit your product list against RAPEX alerts
Find out whether any product in your catalogue appears in an EU Safety Gate (formerly RAPEX) dangerous-products alert. You send a list of items (brand, model number, EAN barcode, product name); you get one result row per item with the matching alerts, how they matched, a confidence score and a link to the official alert. Built for e-commerce sellers, marketplace compliance teams, importers and distributors.
There is also a feed mode: the newest Safety Gate alerts since a date, optionally only those you have not received before.
Important limit: the ECHA REACH Candidate List (SVHC) is not built in. ECHA blocks automated access and its legal notice forbids copying its database. You can paste your own ECHA export to get SVHC matches (see below).
Why use this Actor
- Official source: the European Commission's Safety Gate weekly-report XML downloads. No page scraping, no browser, no proxies.
- Exact matching on barcode (EAN/UPC/GTIN) and model number, plus fuzzy brand + product matching, each with a documented confidence.
- Honest "no match found" rows, so a clean result is visible and auditable (
coverageshows what was searched). - Feed mode with delta: only alerts not delivered before.
- Invalid or unusable input rows are never billed.
Quick start
Click Start with the prefilled input (about 30 seconds, 3 items):
{"mode": "audit","items": [{"reference": "demo-1", "brand": "Goki", "productName": "Wooden pull-along ship", "ean": "4013594548496"},{"reference": "demo-2", "brand": "Wicked Costumes", "productName": "Dinosaur toy costume"},{"reference": "demo-3", "brand": "Acme Gizmo Co", "ean": "4006381333931"}],"maxItems": 3,"lookbackMonths": 6}
You will see three dataset rows: an exact barcode match (confidence 1.0), a fuzzy brand + product match (0.7) and a no_match_found row.
What you get
One dataset row per audited item.
| Field | Meaning |
|---|---|
status | match_found, no_match_found, skipped_unauditable or invalid_input |
matchCount, bestConfidence | number of matches (all) and the highest confidence |
safetyGateMatches[] | matchType, confidence, confidenceLevel, matchedOn, and the full alert |
alert | alert number, link, date, category, brand, model, batch, barcode, risk type, hazard, measures, countries, risk level |
svhcMatches[] | matches against the Candidate List rows you supplied |
warnings, coverage | e.g. EAN ignored; reports and alerts searched |
Real sample from a live run on 2026-10-18 (full file: sample_output.json; trimmed):
{"mode": "audit","reference": "demo-1","input": {"reference": "demo-1", "brand": "Goki", "productName": "Wooden pull-along ship", "ean": "4013594548496"},"status": "match_found","charged": true,"matchCount": 1,"bestConfidence": 1.0,"safetyGateMatches": [{"matchType": "barcode_exact","confidence": 1.0,"confidenceLevel": "exact","matchedOn": ["barcode", "brand", "product"],"alert": {"alertNumber": "OR/00117/26","alertUrl": "https://ec.europa.eu/safety-gate-alerts/screen/webReport/alertDetail/10119156","alertDate": "2026-10-16","reportWeek": "2026-W41","productCategory": "Toys","productType": "Wooden toy","brand": "Goki","productName": "Pull-along ship with bead maze","modelOrType": "54849","batchNumber": "124359","barcode": "4013594548496","riskType": "Strangulation","hazardDescription": "The product has a long cord. The cord may become wrapped around the child's neck ...","measuresTaken": "Type of economic operator taking notified measure(s): Distributor | Category of measure(s): Recall of the product from end users | Date of entry into force: Unknown","recallUrl": "https://www.zakladi.si/opoziv-goki-54849","notifyingCountry": "Slovenia","countryOfOrigin": "Unknown","riskLevel": "Other risk levels"}}],"coverage": {"reportsChecked": 26, "alertsIndexed": 1814, "earliestReportDate": "2026-04-24", "latestReportDate": "2026-10-16"}}
Feed rows contain the alert fields directly plus mode: "feed", isNew (delta mode) and checkedAt. Hazard texts and measures are passed through as published. Product photos are not included.
Input fields
| Field | Meaning |
|---|---|
mode | audit (default) or feed |
items | objects with any of brand, productName, category, modelNumber, ean (aliases gtin, barcode, upc), casNumber, ecNumber, substanceName, reference |
maxItems | caps audited items per run (cost cap), default 100 |
lookbackMonths | months of weekly reports to search, default 6, maximum 36 |
minConfidence | default 0.5 (hides weak brand-only hits) |
maxMatchesPerItem | default 10 (matchCount still shows the total) |
svhcCandidateList | optional, your own ECHA rows |
sinceDate, maxAlerts, deltaMode, deltaStoreName | feed mode: date window, cap, delta state store |
cacheStoreName | report cache store; empty disables caching |
Matching rules and confidence
Confidence is a fixed rule score, not a statistical probability.
| Match type | Confidence | Rule |
|---|---|---|
barcode_exact | 1.00 (exact) | Item EAN/UPC/GTIN equals a barcode published in the alert. Only valid GTIN lengths (8, 12, 13, 14) with a correct GS1 check digit are used on both sides, compared left-padded to 14 digits, so EAN-13, UPC-A and GTIN-14 forms match. Float-typed cells (4006381333931.0), spaces and dashes are cleaned; 7 to 11 digit codes are left-padded; other lengths or bad check digits are ignored with a warning. |
model_exact | 0.95 (exact) or 0.70 | Normalised model number equals a model in the alert. It must mix letters and digits, or be at least 6 characters, and not be a placeholder such as "unknown". 0.95 if the brand also matches, 0.70 if the brand is missing on either side. If both brands are known and differ, the hit is discarded. |
brand_product_fuzzy | 0.50 to 0.70 (fuzzy) | All brand words appear in the alert's brand (minus 0.10 if only in its product text). Legal-form and placeholder words (co, inc, de, eu, home, max, unknown, generic, ...) are ignored; the brand needs 4+ characters or must equal the alert brand. At least 2 item keywords (and at least half) must appear in the alert's category, product type or name. Confidence = 0.50 + 0.20 x overlap. Only a trailing plural "s" is stripped, so irregular plurals and other languages are not matched. |
brand_only | 0.30 (weak) | Brand matches, item has no product keywords. Hidden at the default minConfidence. |
An alert matching by several rules is listed once, with the highest confidence and all evidence in matchedOn. Fuzzy matches are leads, not findings: open the alertUrl and compare the product.
ECHA REACH Candidate List (SVHC): bring your own list
Not built in, deliberately:
echa.europa.euanswers automated requests (evenrobots.txt) with a JavaScript bot challenge (HTTP 403). The Actor never tries to get around bot protection.- ECHA's legal notice (chem.echa.europa.eu) forbids replicating "whole or substantial parts of databases" without written permission, reserves the right to block systematic automated collection, and says CAS information belongs to the American Chemical Society.
Instead, paste the Candidate List rows you exported from ECHA yourself into svhcCandidateList. Headers are normalised (lower-case, punctuation removed), so the real ECHA headers work unchanged: Substance name, EC / List no., CAS no., Reason for inclusion, Date of inclusion. Also accepted: substanceName, name, casNumber, cas, ecNumber, ec, reasonForInclusion, dateOfInclusion. Cells with several values (a; b, a / b) are split. Items with casNumber, ecNumber or substanceName are matched (CAS exact 1.0, EC exact 1.0, exact normalised name 0.9). Invalid CAS numbers are ignored with a warning. A supplied list with no usable row fails the run with a clear message (nothing billed).
Pricing (pay per event)
Event item-audited, $3.00 per 1,000 events (set in the Apify Console, not in this repository).
- Audit mode: one event per audited item, whether or not a match was found. A verified "no match" is what you pay for.
- Feed mode: one event per alert returned.
- Free:
skipped_unauditableandinvalid_inputrows, and any run where the weekly reports could not be fully downloaded (the run fails before the first row is written). maxItems/maxAlertsand your maximum cost per run cap the spend; the Actor stops at the limit.- Example: a 2,000-product catalogue audited once a week costs 2,000 x $0.003 = $6.00 per run.
Use with AI agents (MCP, Claude, Cursor, n8n, Make)
The Actor can be called by AI agents through the Apify MCP server:
{ "mcpServers": { "apify": { "url": "https://mcp.apify.com?tools=goobertje/eu-product-recall-compliance-matcher" } } }
Sign in with OAuth in the browser on first use. Example prompts and the input they map to:
- "Is the Goki ship with EAN 4013594548496 in a Safety Gate alert?" ->
{"mode":"audit","items":[{"brand":"Goki","ean":"4013594548496"}],"maxItems":1} - "Check these two supplier models for recalls over the last two years: Wicked Costumes KA-4429 and Faburo AGFATT7013." ->
{"mode":"audit","items":[{"brand":"Wicked Costumes","modelNumber":"KA-4429"},{"brand":"Faburo","modelNumber":"AGFATT7013"}],"lookbackMonths":24,"maxItems":2} - "Show me the 20 newest Safety Gate alerts since 1 October that I have not seen yet." ->
{"mode":"feed","sinceDate":"2026-10-01","maxAlerts":20,"deltaMode":true,"deltaStoreName":"my-agent-feed"}
In n8n, Make or Zapier, use the Apify node or module, pick this Actor and paste the same JSON.
Use cases
- Weekly catalogue check for marketplace sellers before and after sourcing.
- Supplier due diligence on brands, EANs and model numbers for importers and distributors.
- Product-safety alert feed into a compliance or ticketing system (Safety Gate / RAPEX monitoring).
- Evidence trail: a dated "no match found" row with the searched period.
FAQ
Where does the data come from, and is it allowed? From the European Commission's official Safety Gate weekly-report XML downloads, reusable under CC BY 4.0 (Decision 2011/833/EU). robots.txt does not disallow these paths. Each row carries the source line.
How fresh is it? Alerts appear in the weekly report published on Fridays. alertDate is that report's publication date, so alerts of the current week show up with the next Friday report.
How much does a typical run cost? The prefilled 3-item run costs $0.009. 1,000 items cost $3.00.
What if the source blocks or changes? The Actor backs off, then stops on repeated 403/429 and fails clearly without billing. If the XML structure changes, the run fails instead of returning guesses.
Can I schedule it or get only new items? Yes. Schedule weekly (Fridays). Feed mode with deltaMode returns only alerts not delivered before.
What is not included? ECHA SVHC data (bring your own), product photos, and anything not published as a Safety Gate alert.
Limits and honest caveats
- Barcodes are only sometimes published. In a sample week (2026-W41) about half of the alerts had a barcode, about 80% a model/type number, about 30% a batch number and about 60% a brand. An EAN match works only if the authority published the barcode. "No match found" means no matching alert in the searched period was found by these rules. It does not mean the product is safe or compliant.
- Only published Safety Gate alerts are covered; products can be dangerous without an alert.
- Many alerts have no brand or only partial model data. Brand spelling variants are not covered beyond punctuation, accents and case.
- Searched history is
lookbackMonths(maximum 36). Cold-cache runtime is about 1.1 seconds per weekly report: 6 months about 30 seconds, 36 months (about 157 reports) about 5 minutes. Parsed reports are cached in a named store for up to 90 days (reports from the last 4 weeks refresh daily because they can be corrected). - Alerts are de-duplicated by alert number only (the newest report's copy wins).
Legal
Safety Gate data is published by the European Commission and reusable under CC BY 4.0 (Commission reuse policy, Decision 2011/833/EU), with attribution: "Source: European Commission, Safety Gate". The Actor uses plain HTTPS to the official download endpoints with an identifying User-Agent, at most one request per second. Results are informational, not legal advice; always verify against the official alert.
Not affiliated with, endorsed by or sponsored by the European Commission, the Safety Gate / RAPEX network or ECHA.
Found a problem or want a field added? Open an issue on the Actor page.