# Safety Gate Scraper — EU Product Recalls & Safety Alerts (`darknezz/safety-gate-scraper`) Actor

Extract product recalls and safety alerts from the EU Safety Gate (RAPEX) system — toys, electronics, cosmetics, vehicles and more. Filter by product category, notifying country, risk type and date. Official EU open data via the portal's public JSON API, no login or proxies.

- **URL**: https://apify.com/darknezz/safety-gate-scraper.md
- **Developed by:** [Oaida Adrian](https://apify.com/darknezz) (community)
- **Categories:** Business, Automation, News
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 alert extracteds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Safety Gate Scraper — EU Product Recalls & Safety Alerts

Pull official **EU Safety Gate (RAPEX) product recall and safety alerts** as clean structured JSON. The Safety Gate is the European Commission's rapid alert system for dangerous non-food consumer products — toys, electronics, cosmetics, vehicles, childcare articles, clothing and more. Every alert published by national authorities of the EU/EEA lands here.

The data comes straight from the portal's **public JSON API** — no login, no API key, no proxies, no browser. This is official EU open data, refreshed live at run time.

### What you get

- 🔎 **Every alert field** — reference number (e.g. `A12/00123/26`), publication date, product name and category, brands, model types, barcodes, risk types, risk description, legal provisions, measures taken, country of origin, online sellers
- 🗺️ **Notifying country** — which EU/EEA authority reported the alert
- 🛒 **E-commerce angle** — `isSoldOnline` flag and the online marketplaces/traders where the product was sold
- 🖼️ **Product photos** — direct URL to the main image from the official record
- 📅 **Date-filtered** — pull alerts published since a specific date (e.g. a weekly compliance sweep)

### Input

```json
{
  "category": "Electrical appliances and equipment",
  "country": "DE",
  "dateFrom": "2026-07-01",
  "extractDetails": true
}
```

| Field | Type | Default | Description |
|---|---|---|---|
| `category` | string | empty | Product category — name or API code, e.g. `Electrical appliances and equipment`, `ELECTRICAL_APPLIANCES`, `Toys`, `Cosmetics`. Empty = all categories. |
| `country` | string | empty | Notifying country — ISO code or name, e.g. `DE`, `Germany`, `FR`. Empty = all countries. |
| `dateFrom` | string | empty | Only alerts published on/after this date (`YYYY-MM-DD`). |
| `dateTo` | string | empty | Only alerts published on/before this date (`YYYY-MM-DD`). |
| `riskType` | string | empty | Filter by risk, e.g. `ELECTRIC_SHOCK`, `FIRE`, `CHEMICAL`, `CHOKING`, `INJURIES`. |
| `maxResults` | integer | 0 | Maximum alerts to extract. `0` = unlimited (all matches). |
| `extractDetails` | boolean | true | Fetch the full detail record per alert (risk description, measures, origin, sellers). When `false`, returns the faster search-card fields only. |
| `language` | string | `en` | Language for descriptions and product names (`en`, `de`, `fr`, `ro`, ...). |

### Output

One dataset item per alert:

```json
{
  "id": 10118484,
  "reference": "SR/02255/26",
  "alertUrl": "https://ec.europa.eu/safety-gate-alerts/screen/webReport/alertDetail/10118484",
  "publicationDate": "2026-08-11T12:14:17.333+00:00",
  "notifyingCountryCode": "DE",
  "notifyingCountry": "Germany",
  "productCategory": "ELECTRICAL_APPLIANCES",
  "productName": "Electric grinder",
  "productNameSpecific": "Elektrische Gewürz- und Kaffeemühle, Electric Grinder",
  "brands": ["Yearninglife"],
  "modelTypes": ["8300"],
  "barcodes": ["6851451218421"],
  "riskTypes": ["CUTS", "ELECTRIC_SHOCK"],
  "riskDescription": "The appliance can be used with the lid open, allowing direct contact with the grinding blade...",
  "legalProvision": "The product does not comply with the requirements of the Low Voltage Directive...",
  "measures": ["PRODUCT_WITHDRAWAL_FROM_MARKET"],
  "countryOriginCode": "CN",
  "countryOrigin": "People's Republic of China",
  "isSoldOnline": true,
  "onlineTraders": ["eBay"],
  "webReportCode": "Report-2026-32",
  "mainImageUrl": "https://ec.europa.eu/safety-gate-alerts/public/api/notification/image/11228256",
  "scrapedAt": "2026-08-13T10:00:00+00:00"
}
```

Fields not published for an alert come back as `null`/empty — every record keeps the same shape, so CSV/Excel exports stay clean.

### Use cases

- **Compliance monitoring** — watch a product category you sell or import; get alerted when a product is flagged
- **Marketplace seller risk** — check `onlineTraders` to see which platforms a recalled product was sold on
- **Product safety research** — analyse recall trends by category, country and risk type
- **Quarterly EU safety reports** — pull all recalls in a category and measure reporting trends
- **Import/KYC vetting** — screen a supplier's catalogue against the official EU recall database

### Run it on a schedule or from your code

Create a Schedule in Apify Console to run a weekly category sweep, or call the Actor from anywhere:

```bash
curl -X POST "https://api.apify.com/v2/acts/darknezz~safety-gate-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"category": "Toys", "dateFrom": "2026-08-01"}'
```

The call returns the alerts directly as JSON. Every run's dataset can also be exported as CSV, Excel, XML or RSS from Apify Console.

From Python with the official SDK:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_TOKEN")
run = client.actor("darknezz/safety-gate-scraper").call(
    run_input={"category": "Electrical appliances and equipment",
               "country": "DE", "dateFrom": "2026-07-01"})
for alert in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(alert["reference"], alert["productName"], alert["riskTypes"])
```

### Pricing

Pay-per-event: **$0.02 per alert extracted**, plus Apify's standard compute. A weekly sweep of one category typically costs under a dollar.

### FAQ

**Where does the data come from?** The official EU Safety Gate portal (`ec.europa.eu/safety-gate-alerts`) — the European Commission's public JSON API. The same source the portal's own website uses. No scraping of HTML pages, no fragile selectors.

**How fresh is it?** Alerts are pulled live at run time. The Commission publishes new alerts weekly (every Friday) plus immediate publications for serious risks.

**What categories exist?** Toys, electrical appliances and equipment, cosmetics, clothing/textiles, childcare articles, motor vehicles, chemicals, furniture, machinery, personal protective equipment, and more — the full list is in the `category` dropdown.

**Does `country` mean where the product was made?** No — it filters by the **notifying** country (the EU/EEA authority that reported the alert). The country of *origin* (e.g. China) is a separate field on each record: `countryOrigin`.

**Are these the same alerts as the weekly RAPEX report?** Yes. Safety Gate is the successor of RAPEX; every alert notified under the GPSD/Regulation (EU) 2023/988 appears in this database.

**Is this legal?** Yes — the EU publishes this data openly for reuse, with attribution. The Actor preserves official content and includes the `alertUrl` link to the authoritative record in every row. Verify current measures on the linked official alert before taking compliance or legal action.

**Can I get alerts from all countries at once?** Yes — leave `country` empty. Use `dateFrom` to bound the window so large pulls stay fast.

# Actor input Schema

## `category` (type: `string`):

Filter by product category. Use a category name or its API code, e.g. 'Electrical appliances and equipment', 'ELECTRICAL\_APPLIANCES', 'Toys', 'TOYS', 'Cosmetics'. Leave empty for all categories.

## `country` (type: `string`):

Filter by the country that reported the alert. ISO 3166-1 alpha-2 code or full name, e.g. 'DE', 'Germany', 'FR', 'France'. Leave empty for all countries.

## `dateFrom` (type: `string`):

Only alerts published on or after this date. Format YYYY-MM-DD, e.g. '2026-07-01'. Leave empty for no lower bound.

## `dateTo` (type: `string`):

Only alerts published on or before this date. Format YYYY-MM-DD, e.g. '2026-12-31'. Leave empty for no upper bound.

## `riskType` (type: `string`):

Filter by risk type, e.g. 'ELECTRIC\_SHOCK', 'FIRE', 'CHEMICAL', 'CHOKING', 'INJURIES'. Leave empty for all risks.

## `maxResults` (type: `integer`):

Maximum number of alerts to extract. Set to 0 for unlimited (all matching alerts).

## `extractDetails` (type: `boolean`):

Fetch each alert's full detail record (risk description, legal provisions, measures, origin country, online sellers). When false, returns the faster search-card fields only.

## `language` (type: `string`):

Language code for descriptions and product names (en, de, fr, ro, ...).

## Actor input object example

```json
{
  "category": "Electrical appliances and equipment",
  "country": "DE",
  "dateFrom": "2026-07-01",
  "maxResults": 0,
  "extractDetails": true,
  "language": "en"
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "category": "Electrical appliances and equipment",
    "country": "DE",
    "dateFrom": "2026-07-01",
    "riskType": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("darknezz/safety-gate-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "category": "Electrical appliances and equipment",
    "country": "DE",
    "dateFrom": "2026-07-01",
    "riskType": "",
}

# Run the Actor and wait for it to finish
run = client.actor("darknezz/safety-gate-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "category": "Electrical appliances and equipment",
  "country": "DE",
  "dateFrom": "2026-07-01",
  "riskType": ""
}' |
apify call darknezz/safety-gate-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,darknezz/safety-gate-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/MCZNtXLUkvUHf1ams/builds/OccHMgCEdAWgHI3qT/openapi.json
