# EU Safety Gate API (`sourcing-data-studio/eu-safety-gate-api`) Actor

Unofficial EU Safety Gate API: European Commission RAPEX alerts on dangerous non-food products by keyword, category and country of origin, with product, risk, measures taken and picture links. You pay only for alerts saved.

- **URL**: https://apify.com/sourcing-data-studio/eu-safety-gate-api.md
- **Developed by:** [Sourcing Data Studio](https://apify.com/sourcing-data-studio) (community)
- **Categories:** E-commerce, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.40 / 1,000 alert results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

Check whether a product type has been flagged as dangerous in the EU before you buy it. EU Safety Gate API returns the alerts of the European Commission Safety Gate (RAPEX) as clean rows, filtered by keyword, category and country of origin: product, brand, risk, danger, measures taken and picture links. Use it for supplier checks, compliance reviews and AI agents. You pay only for alerts saved: $0.003 per alert result on the Free tier, so a typical query (the 20 newest alerts for one keyword) costs $0.06.

Unofficial: not affiliated with or endorsed by the European Commission.

Source: European Commission, Safety Gate: the EU rapid alert system for dangerous non-food products. Reused under CC BY 4.0; changes made: fields selected and normalised.

Importers, product-safety teams and marketplace compliance teams use it as an EU product compliance check: screen a product type or brand before you buy, and see which products of a given origin were stopped. As a RAPEX API it returns product safety alerts and EU product recalls for spreadsheets, databases and AI agents. To list dangerous products from China, set the country of origin to China; the same filter gives Safety Gate alerts by country of origin for any other country. The data comes from the public weekly reports on ec.europa.eu.

### What does EU Safety Gate API do?

- Reads the newest weekly Safety Gate reports, newest first.
- Keeps the alerts that match your keywords, country of origin and category. Every filter is optional.
- Understands official country names and country codes, so "People's Republic of China", "PRC", "CN" and "China" are the same.
- Removes duplicates by alert number and rejects incomplete rows before they are saved.
- Charges one event per saved alert. Failed requests, duplicates and invalid rows are never charged.
- Tells a real "no match" from a failed read. A run that saved nothing ends as failed, and says why, when it could not read every weekly report, did not get to every weekly report, was stopped early or found reports without alerts. A run that nothing stopped, that saved alerts and did not get to every weekly report, says how many were not read. A run that Apify restarted is the exception: it says that it was restarted, because it cannot tell which weekly reports were read before.
- Writes a run summary with totals, failures and the source attribution to the key-value store.
- Works from Apify Console, the Apify API, n8n, Make and AI agents through the Apify MCP server.

### Output example

These rows come from a real run.

```json
[
  {
    "alertNumber": "SR/02679/26",
    "reportReference": "Report-2026-39",
    "publicationDate": "2026-10-02",
    "category": "Toys",
    "product": "Toy car",
    "brand": null,
    "name": "Bébé ramper jouet voitures jouets pour 1 2 3 ans",
    "model": "8804",
    "batchNumber": null,
    "barcode": "6971601780414",
    "riskType": "Choking",
    "riskLevel": "Serious risk",
    "danger": "The toy has a small part (left rear wheel) that can easily detach. Small children could put it in the mouth and choke. The product does not comply with the requirements of the Toy Safety Directive nor with the European Standard EN 71-1.",
    "measures": "Type of economic operator taking notified measure(s): Other; Category of measure(s): Withdrawal of the product from the market; Date of entry into force: 2026-07-17 | Type of economic operator taking notified measure(s): Other; Category of measure(s): Warning consumers of the risks; Date of entry into force: 2026-07-22",
    "countryOfOrigin": "China",
    "notifyingCountry": "France",
    "description": "Black plastic toy police car.",
    "imageUrls": [
      "https://ec.europa.eu/safety-gate-alerts/public/api/notification/image/11236095",
      "https://ec.europa.eu/safety-gate-alerts/public/api/notification/image/11236096",
      "https://ec.europa.eu/safety-gate-alerts/public/api/notification/image/11236097"
    ],
    "url": "https://ec.europa.eu/safety-gate-alerts/screen/webReport/alertDetail/10118426",
    "searchQuery": "toy",
    "source": "EU Safety Gate",
    "retrievedAt": "2026-10-05T14:55:32.229Z"
  },
  {
    "alertNumber": "SR/02629/26",
    "reportReference": "Report-2026-39",
    "publicationDate": "2026-10-02",
    "category": "Toys",
    "product": "Plastic toy",
    "brand": null,
    "name": "Mini Multi-Functional Busy Board Montessori Educational Early Learning Toy",
    "model": "sl251116616091063966",
    "batchNumber": "20260320",
    "barcode": null,
    "riskType": "Choking, Strangulation",
    "riskLevel": "Serious risk",
    "danger": "The toy has small parts (plastic components) that can easily detach. A small child could put them in the mouth and choke. Moreover, the product contains cords/chains that are too long. They could entangle around the neck of the child and create a risk of strangulation. The product does not comply with the requirements of the Toy Safety Directive nor with the European standard EN 71-1.",
    "measures": "Type of economic operator taking notified measure(s): Other; Category of measure(s): Removal of this product listing by the online marketplace; Date of entry into force: 2026-08-06 | Type of economic operator taking notified measure(s): Other; Category of measure(s): Recall of the product from end users; Date of entry into force: 2026-08-17",
    "countryOfOrigin": "China",
    "notifyingCountry": "Ireland",
    "description": "Plastic toy consisting of a vehicle with interactive elements in various colours.",
    "imageUrls": [
      "https://ec.europa.eu/safety-gate-alerts/public/api/notification/image/11236140",
      "https://ec.europa.eu/safety-gate-alerts/public/api/notification/image/11236141"
    ],
    "url": "https://m.shein.com/euqs/ark/5343?scene_type=recall&banner_delivery_id=6698008",
    "searchQuery": "toy",
    "source": "EU Safety Gate",
    "retrievedAt": "2026-10-05T14:55:32.229Z"
  },
  {
    "alertNumber": "SR/02735/26",
    "reportReference": "Report-2026-39",
    "publicationDate": "2026-10-02",
    "category": "Toys",
    "product": "Dance mat",
    "brand": null,
    "name": "Wii Dance mat",
    "model": null,
    "batchNumber": null,
    "barcode": null,
    "riskType": "Chemical, Environment",
    "riskLevel": "Serious risk",
    "danger": "The solders in the product have an excessive concentration of lead and cadmium (measured value: up to 69.8% and 0.36% by weight, respectively). Lead poses a risk to the environment.Cadmium bio-accumulates and poses a risk to the environment. The plastic material of the cable has an excessive concentration of bis(2-ethylhexyl) phthalate (DEHP) and short chain chlorinated paraffins (SCCPs) (measured value up: 0.53% and 0.95% by weight, respectively). This phthalates poses a risk to human health and the environment. SCCPs persist in the environment, are toxic to aquatic organisms at low concentrations and bio-accumulate in wildlife and humans, posing a risk to human health and the environment. The product does not comply with the requirements of the Commission Directive on the restriction of the use of certain hazardous substances in electrical and electronic equipment (RoHS Directive) nor with the Persistent Organic Pollutants (POP) Regulation.",
    "measures": "Type of economic operator taking notified measure(s): Distributor; Category of measure(s): Withdrawal of the product from the market; Date of entry into force: 2026-07-01",
    "countryOfOrigin": "China",
    "notifyingCountry": "Sweden",
    "description": "Electrical dance mat game.",
    "imageUrls": [
      "https://ec.europa.eu/safety-gate-alerts/public/api/notification/image/11236172",
      "https://ec.europa.eu/safety-gate-alerts/public/api/notification/image/11236173"
    ],
    "url": "https://ec.europa.eu/safety-gate-alerts/screen/webReport/alertDetail/10118892",
    "searchQuery": "toy",
    "source": "EU Safety Gate",
    "retrievedAt": "2026-10-05T14:55:32.229Z"
  }
]
```

### What data can you get with EU Safety Gate API?

Each row is one alert. The main fields are the product, brand, model and barcode, the type of risk and the danger, the measures taken, the country of origin, the country that sent the alert, picture links and a link to the recall notice or the alert page. All dates are ISO dates (YYYY-MM-DD).

| Field | Type | Description |
|---|---|---|
| `alertNumber` | string | Safety Gate case number of the alert, for example SR/02365/26. Unique within a run. |
| `reportReference` | string | Weekly report that published the alert, for example Report-2026-39. |
| `publicationDate` | string | Publication date of the weekly report, as an ISO date (YYYY-MM-DD). |
| `category` | string | Safety Gate product category, for example Toys or Electrical appliances and equipment. |
| `product` | string | Short product description, for example Toy figure. |
| `brand` | string, optional | Brand of the product, when the alert names one. |
| `name` | string, optional | Product name as given in the alert, when present. |
| `model` | string, optional | Type or model number, when present. |
| `batchNumber` | string, optional | Batch number, when present. |
| `barcode` | string, optional | Barcode (EAN or similar), when present. |
| `riskType` | string | Type of risk, for example Chemical, Choking or Fire. |
| `riskLevel` | string, optional | Risk level as given by the notifying authority, for example Serious risk, when present. |
| `danger` | string | Why the product is dangerous, in the words of the notifying authority. E-mail addresses and phone numbers are replaced with \[contact removed]. |
| `measures` | string, optional | Measures taken. Label and value pairs are joined with '; ' and separate measures with ' | '. The date of entry into force is an ISO date (YYYY-MM-DD). |
| `countryOfOrigin` | string | Country where the product was made, with official spellings normalised (for example China). Unknown when the alert gives none. |
| `notifyingCountry` | string | EU or EEA country that sent the alert. |
| `description` | string, optional | Description of the product, when present. It is the Commission's alert text, quoted as published, so it can name a shop or marketplace. E-mail addresses and phone numbers are replaced with \[contact removed]. The seller fields of the alert are not collected. |
| `imageUrls` | array | Links to the product pictures on the Safety Gate site. Images are not copied. |
| `url` | string, optional | Link to the recall notice when the alert has one, otherwise to the alert's Safety Gate page. A recall notice can be on the site of an authority, a manufacturer or a shop. Links to social media and links that contain an e-mail address are not used. |
| `searchQuery` | string, optional | Keyword that matched the alert, or null when no keyword was set. |
| `source` | string | Name of the data source: EU Safety Gate. |
| `retrievedAt` | string | ISO 8601 time when the alert was collected. |

### How to use EU Safety Gate API

1. Click **Try for free** on this page.
2. Enter one or more **Keywords**, for example `toy` or `charger`. Leave the field empty to get every alert in the scanned weeks.
3. Optionally set a **Country of origin**, such as China, and a **Category**, such as Toys.
4. Set **Weekly reports to scan** (8 by default, about two months) and **Maximum alerts**. The run stops as soon as that many alerts are saved.
5. Click **Start**. Results appear in the **Output** tab while the run is going.
6. Download the results as JSON, CSV or Excel, or read them through the API.

A keyword matches when each of its words starts a word in the product, name, brand, category or description of an alert. So `toy` finds "toy" and "toys", and `car` finds "car", "cars" and "cartridge", but not "scarf". Capital letters and accents do not matter. An alert needs to match only one of your keywords.

### Input examples

#### Quick test

```json
{
  "searchQueries": [
    "toy"
  ],
  "countryOfOrigin": "China",
  "maxItems": 10
}
```

#### Chargers and power banks

```json
{
  "searchQueries": [
    "charger",
    "power bank"
  ],
  "maxWeeks": 26,
  "maxItems": 100
}
```

#### Cosmetics last year

```json
{
  "category": "Cosmetics",
  "maxWeeks": 52,
  "maxItems": 200,
  "feedback": "Example: please add a filter for the risk type."
}
```

### How much does EU Safety Gate API cost?

| Event | You pay for | Free | Bronze | Silver | Gold |
|---|---|---|---|---|---|
| Alert result | One Safety Gate alert saved to the dataset. Failed requests, duplicates and invalid rows are never charged. | $0.003 | $0.003 | $0.0027 | $0.0024 |

Prices are per event. Your tier follows your Apify subscription plan.

On the Free tier, $0.003 per alert result means:

- 100 alert results cost $0.30.
- 1,000 alert results cost $3.00.
- A typical query (the 20 newest alerts for one keyword) is 20 alert results and costs $0.06.

Apify also charges a tiny start fee per run (apify-actor-start, $0.00005 per GB of memory). Failed requests, duplicates and invalid rows are never charged. To cap your spending, set **Maximum cost per run** in the run options; the run stops cleanly when that budget is used.

### Use EU Safety Gate API from the API, n8n, Make or an AI agent

#### Apify API

Run the Actor and get the alerts in one call:

**curl**

```bash
curl -X POST "https://api.apify.com/v2/acts/sourcing-data-studio~eu-safety-gate-api/run-sync-get-dataset-items" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"searchQueries":["toy"],"countryOfOrigin":"China","maxItems":10}'
```

**JavaScript** (Node.js, `npm install apify-client`)

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });

const input = {
    "searchQueries": [
        "toy"
    ],
    "countryOfOrigin": "China",
    "maxItems": 10
};

const run = await client.actor('sourcing-data-studio/eu-safety-gate-api').call(input);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**Python** (`pip install "apify-client>=3"`, Python 3.11 or later)

```python
import os

from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run_input = {
    "searchQueries": [
        "toy"
    ],
    "countryOfOrigin": "China",
    "maxItems": 10
}

run = client.actor("sourcing-data-studio/eu-safety-gate-api").call(run_input=run_input)

for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)
```

#### n8n and Make

Use an HTTP request module with the same URL, method POST and a JSON body like the input examples above. Store your Apify API token as a credential, never in the workflow itself.

#### AI agents through the Apify MCP server

Connect your agent to the Apify MCP server and call `sourcing-data-studio/eu-safety-gate-api` with the same input. Agents can use the **Feedback for the developer** field to report missing fields or problems.

### For AI agents

- Minimal input: `{"searchQueries":["charger"],"countryOfOrigin":"China","maxItems":10}`. At the Free price, 10 alerts cost $0.03 plus the platform's start fee.
- Read first: `product`, `riskType`, `danger`, `measures` and `url`.
- Outcomes: the run status message and the `RUN_SUMMARY` record in the run's key-value store. There `listings` gives each request one status (`ok`, `failed` or `blocked`) and `scan.stopReason` says why a scan ended early. `scan.reportsNotRead` counts the weekly reports that were planned but not read, although nothing stopped the run and no request for them failed. `totals.extraPasses` counts how often the crawler was started again, and `totals.requestsLeft` counts the requests that were still waiting at the end. `restarted` is `true` when Apify restarted the run. The counts in the record then cover only the part of the run after the restart, and `scan.reportsPlanned` is 0 when the list of weekly reports was read before the restart. Such a run stopped after the weekly report that was waiting, so older weekly reports may not have been read and its rows may be incomplete. A run that saved nothing ends as `SUCCEEDED` only in three cases: it read every planned weekly report and no alert matched, it stopped at your **Maximum cost per run** before it could save an alert, or Apify restarted it, because alerts may have been saved before the restart. Otherwise it ends as `FAILED` and the message says why. A run that saved alerts ends as `SUCCEEDED`, also when `scan.reportsNotRead` is above 0. The message then says how many weekly reports were not read, and alerts from those weeks may be missing. `scan.reportsNotRead` is 0 for a run that was stopped on purpose and for a run that Apify restarted.
- Do not use it as proof that a product is safe or compliant, or for recalls outside the EU Safety Gate system: no alert in the results only means that none was published in the weeks scanned.
- Callable through the Apify MCP server as the tool `sourcing-data-studio/eu-safety-gate-api` and through the Apify API.

### Limits

- Only alerts that the Commission has published in a weekly report are included. A new report appears about once a week, so the newest alerts can be a few days old.
- Each run reads at most 104 weekly reports and saves at most 5,000 alerts. For more, run the Actor several times.
- Each weekly report is one request, sent slowly to be polite to the source. A run over many weeks takes several minutes.
- Keyword matching is a text match, not a product classification. Try a few spellings, for example `charger` and `power bank`.
- For some alerts the source gives no country of origin. Their `countryOfOrigin` is `Unknown`, and a country filter leaves them out.
- If no alert has the country you asked for, the run message lists the countries that were found, so you can pick the right name.
- If two weekly reports in a row cannot be read, or the source asks for a long pause or says that its request limit is used up, the scan stops there. The run message says so and the alerts saved so far are kept. A run that saved nothing ends as failed in that case, not as "no match".
- The crawler (the part of EU Safety Gate API that reads the reports) may end while a request is still waiting. The weekly reports behind that request are then not read. EU Safety Gate API checks for this when the crawler ends. Without a proxy, which is the default, it starts the crawler again for the waiting request, up to three times, and writes a `run.pending` line to the log each time. With a proxy it does not: a new start could use another proxy address, and EU Safety Gate API does not move a run to another address by itself. It then only reports what is left. The run summary counts the new starts and the requests that were still left under `totals` (`extraPasses` and `requestsLeft`), and `scan.reportsNotRead` counts the weekly reports that were not read. When nothing stopped the run, Apify did not restart it, and it did not get to every weekly report, the message says how many were not read. The run ends as succeeded when it saved alerts, and as failed when it saved nothing. Nothing is charged for alerts that were not saved. Run it again if you need those weeks. A new run reads every weekly report again and charges for every alert it saves, also for alerts that an earlier run saved.
- Apify can restart a run, for example when it moves the run to another server. EU Safety Gate API does not keep its list of weekly reports across a restart. When the list had been read before the restart, the run cannot go on to the weekly reports that were still to be read. It reads at most the weekly report that was already waiting, and then it ends. Older weekly reports may not have been read, and the run cannot tell which weekly reports were read before the restart. A new run reads every weekly report again and charges for every alert it saves. After a restart **Maximum alerts** counts again from 0, while **Maximum cost per run** counts the whole run.
- The status message of a restarted run says that the run was restarted. When it had no list of weekly reports and nothing stopped it, the message also says how many weekly reports it read after the restart, and that older weekly reports may not have been read. It does not say how many weekly reports were not read, because it cannot tell. The alerts saved before the restart are in the dataset. With pay per event, the message also gives the number of alerts the run has saved in all, before and after the restart. That number is the charging count that Apify keeps for the run. When it is 0, the message says that no alerts were saved, before or after the restart. The numbers in the run summary (`scan`, `totals`, `listings` and `billing`) count only the part of the run after the restart, and `restarted` is `true` there. A restarted run does not end as failed because it saved no alerts, since alerts may have been saved before the restart.
- Alerts are de-duplicated within a run, not across runs.
- The download links of the weekly reports are not documented by the Commission and could change. If a report cannot be read, it is listed in the run summary and nothing is charged for it. A report that lists no alerts at all counts as unreadable, because its format has probably changed.

### FAQ

#### Which data does EU Safety Gate API collect?

Only public alert data from the Safety Gate weekly reports: product details, risk, measures, countries and picture links. Picture links point to the Safety Gate site; the images themselves are not copied.

#### Which data is not collected?

The seller fields of an alert, such as the online trader, are not collected, and the row has no field for sellers or contact persons. The `description` is the Commission's own alert text and is quoted as published, so it can name a shop or marketplace, for example where the product was sold online. If an email address or a phone number appears in the description or the danger text, it is replaced with `[contact removed]`. The Actor does not log in and does not use cookies.

The `url` field can point to a recall notice outside the Safety Gate site, as the alert gives it: a national authority's recall portal, or the recall page of a company, which can be the manufacturer or the shop that sold the product. A recall link that points to a social-media post or contains an email address is not used; the row then links to the alert's Safety Gate page.

#### Where does the data come from, and may I reuse it?

The data comes from the Safety Gate service of the European Commission. The Commission's [legal notice](https://commission.europa.eu/legal-notice_en) allows reuse of its content under the [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) licence. When you publish the data, give the attribution shown at the top of this page and say that changes were made.

#### Why did my run return 0 alerts?

Look at the run status. A run that ends as **Succeeded** read the weekly reports and found no alert that matches your filters: try more **Weekly reports to scan**, fewer filters or another spelling. The run message tells you when the country of origin was the filter that matched nothing, and which country names were found. Two other kinds of run also end as **Succeeded** without an alert, and their message says so. One stopped at your **Maximum cost per run** before it could save an alert. The other was restarted by Apify: a restarted run does not keep its list of weekly reports, so older weekly reports may not have been read. A run that ends as **Failed** cannot tell whether anything matched: a weekly report could not be read or was refused, the run ended before it got to every weekly report, the scan was stopped early (by the source, or because the run timeout was near), or the reports held no alerts at all. The run message names the cause, and the run summary in the **Storage** tab shows how many reports were read and lists each failed request. Nothing is charged for failed requests. Run it again later.

#### What happens when the source blocks a report or limits requests?

A report that the source refuses (HTTP 401, 403 or 407), or that turns out to be a verification or access-denied page, is not asked for again in the same run. It is listed as blocked in the run summary and nothing is charged for it. If the next report is refused too, the scan stops.

When the source says that it gets too many requests (HTTP 429), EU Safety Gate API waits as long as the source asks (the `Retry-After` header, at most two minutes) and asks again from the same address, as often as **Retries per request** allows. When the source says that no requests are left (`x-ratelimit-remaining: 0`) or asks for a longer pause, the scan stops there. EU Safety Gate API never switches to another proxy address to get around a refusal or a limit. Run it again later instead.

#### Is this an official Safety Gate service?

No. This Actor is unofficial and not affiliated with or endorsed by the European Commission. For legal decisions, check the alert on the Safety Gate site. The `url` field opens the alert there for about 88 rows in 100 (3,487 of 3,977 rows in the 52 weekly reports to 9 October 2026); when `url` is a recall notice instead, search the `alertNumber` on the Safety Gate site.

#### Can I schedule EU Safety Gate API?

Yes. Save your input as a task and add a schedule in Apify Console, for example a weekly check of your product types.

### Feedback

Tell us what to add next in the **Feedback for the developer** input field, or open an issue in the **Issues** tab. Feedback is saved with the run summary.

# Changelog

This Actor's version history is a separate document: https://apify.com/sourcing-data-studio/eu-safety-gate-api/changelog.md

# Actor input Schema

## `searchQueries` (type: `array`):

Optional keywords, for example toy, charger or a brand name. Each keyword is matched without regard to capital letters or accents in the product, name, brand, category and description of an alert; an alert is kept when it matches at least one keyword. Every word of a keyword must start a word of the alert text, so toy finds toys and car does not find scarf. Leave empty to return every alert that passes the other filters.

## `countryOfOrigin` (type: `string`):

Optional. Only alerts for products made in this country, for example China, Türkiye or Vietnam. Official spellings and two-letter country codes are understood, so People's Republic of China, PRC, CN and China are the same. Leave empty for all countries.

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

Optional. Only alerts whose Safety Gate category contains this text, for example Toys, Cosmetics, Electrical appliances or Motor vehicles. Capital letters do not matter. Leave empty for all categories.

## `maxWeeks` (type: `integer`):

How many of the newest weekly Safety Gate reports to scan, newest first. A new report is published every Friday, so 8 covers about two months and 104 about two years. Each report is one request, sent slowly.

## `maxItems` (type: `integer`):

Maximum number of alerts to save and pay for in this run, across all keywords and weeks. The run stops as soon as this many alerts are saved. Alerts are de-duplicated by alert number.

## `proxyConfiguration` (type: `object`):

Optional. The source is a public European Commission download and needs no proxy, so none is used by default. Turn on Apify Proxy or add your own proxy servers only if your network needs it. A proxy is never used to get around a refusal or a rate limit: a request that is asked for again leaves from the same address.

## `maxRequestRetries` (type: `integer`):

How many times a failed request is retried after a pause: exponential backoff, or the pause the source asks for after HTTP 429. A request that the source refuses (HTTP 401, 403 or 407) is not retried. A retry leaves from the same address, never from another one. Failed requests are never charged. The scan stops when two weekly reports in a row cannot be read.

## `debugLog` (type: `boolean`):

Print detailed debug messages to the run log.

## `feedback` (type: `string`):

Optional. Tell us which field, filter or data source you need next, or what went wrong. It is saved with the run summary. Do not include personal data. AI agents may also use this field to report problems.

## Actor input object example

```json
{
  "searchQueries": [
    "toy"
  ],
  "countryOfOrigin": "China",
  "maxWeeks": 8,
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "maxRequestRetries": 3,
  "debugLog": false
}
```

# Actor output Schema

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

No description

## `summary` (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 = {
    "searchQueries": [
        "toy"
    ],
    "countryOfOrigin": "China",
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("sourcing-data-studio/eu-safety-gate-api").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 = {
    "searchQueries": ["toy"],
    "countryOfOrigin": "China",
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("sourcing-data-studio/eu-safety-gate-api").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 '{
  "searchQueries": [
    "toy"
  ],
  "countryOfOrigin": "China",
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call sourcing-data-studio/eu-safety-gate-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sourcing-data-studio/eu-safety-gate-api"
        }
    }
}
```

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/wqMIi41rA5sq2QWVO/builds/IXdO1dhE3h6QYoK6B/openapi.json
