# EU Food Import Controls Monitor (Reg 2019/1793) (`chosen_loafer/eu-food-import-monitor`) Actor

Checks a watchlist of commodity/origin-country pairs against EU Regulation 2019/1793's consolidated import-control annexes. Reports CN code, hazard, inspection frequency and conditions, with explicit change states (FIRST_SEEN, UNCHANGED, FREQUENCY_CHANGED, ADDED, REMOVED). No personal data.

- **URL**: https://apify.com/chosen_loafer/eu-food-import-monitor.md
- **Developed by:** [Pavel Staurouski](https://apify.com/chosen_loafer) (community)
- **Categories:** Automation, Business, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 watchlist item checkeds

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/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

## EU Food Import Controls Monitor (Reg 2019/1793)

Checks a watchlist of commodity/origin-country combinations against the EUR-Lex
consolidated text of Commission Implementing Regulation (EU) 2019/1793 (temporary
increase of official controls and emergency measures governing the entry into the
Union of certain food and feed of non-animal origin from certain third countries).

### What you get

One record per watchlist item per matched annex entry: which annex it comes from
(Annex I = temporary increase of official controls, Annex II = special conditions due
to mycotoxin/pesticide/microbiological/Sudan-dye/plant-toxin risk, Annex IIa =
suspension of entry), the CN code (with the "ex" qualifier and TARIC sub-division
preserved exactly as published), product description, origin country (and dispatch
country, where the annex states one separately), hazard, inspection frequency, and the
resolved text of any footnoted special condition - not just a bare superscript number.

Every record also carries an explicit state: `FIRST_SEEN`, `UNCHANGED`,
`FREQUENCY_CHANGED`, `HAZARD_CHANGED`, `CONDITIONS_CHANGED`, `ADDED`, `REMOVED`,
`NOT_LISTED`, `INVALID_INPUT`, or `FETCH_ERROR`. A failed fetch always produces an
explicit `FETCH_ERROR` record per watchlist item, never a silent "no change" - and
never touches your previously-saved comparison state, so the next successful run still
compares against the last known-good snapshot.

### What it does not do

No legal advice, no certification. This is a documentation tool over the EU's own
documentation-tool consolidated text (EUR-Lex's own disclaimer: "has no legal effect";
the authentic version is the Official Journal). No personal data: entries are about
commodities, countries and chemical/legal references, never contact names or
signatories.

### Why you might need this

An import-compliance manager, customs broker, or supplier-quality team sourcing a
specific commodity from a specific third country needs to know immediately when that
exact combination's inspection frequency rises, a special condition is added, or the
commodity is suspended outright. Missing one of these changes means a consignment
arrives at the border control post cleared for the old frequency and gets pulled for
the new, stricter one anyway, with demurrage and storage costs accruing while customs
re-checks it, or outright rejected if the commodity was suspended since the last time
anyone read the annex by hand. The Commission issues an amending regulation roughly
every 4-8 weeks in practice, which is too often to re-read the whole consolidated annex
manually before every shipment.

### Input

```json
{
  "watchlist": [
    { "cnCode": "1202 42 00", "originCountry": "Argentina" },
    { "productKeyword": "betel leaves", "originCountry": "Bangladesh" },
    { "cnCode": "0802 51 00", "originCountry": "United States" }
  ]
}
```

Each watchlist item needs `originCountry` (full name or ISO-2 code, e.g. "Argentina"
or "AR") plus at least one of `cnCode` (matched against the published CN code; an
"ex"-qualified annex entry is matched as a prefix in either direction) or
`productKeyword` (case-insensitive substring match against the published product
description). If both are given on one item, both must match.

### Sample output

```json
{
  "entryId": "II-1|1|BD|14049000|Foodstuffs containing or consisting of betel leaves (Piper betle) (Food)",
  "annex": "II-1",
  "annexLabel": "1. Food and feed of non-animal origin referred to in Article 1(1), point (b)(i)",
  "rowNumber": "1",
  "originCountry": "Bangladesh",
  "originCountryCode": "BD",
  "dispatchCountry": null,
  "dispatchCountryCode": null,
  "productDescription": "Foodstuffs containing or consisting of betel leaves (Piper betle) (Food)",
  "cnCode": "ex 1404 90 00",
  "cnCodeNormalized": "14049000",
  "cnCodeIsEx": true,
  "taricSubdivision": "10",
  "hazard": "Salmonella",
  "frequencyPercent": 50,
  "frequencyRaw": "50",
  "specialConditions": [
    "Foodstuffs containing or consisting of betel leaves (Piper betle) including, but not limited to, those declared under CN code 1404 90 00.",
    "The sampling and the analyses shall be performed in accordance with the sampling procedures and the analytical reference methods set out in point 1(a) of Annex III."
  ],
  "matchedVia": "originCountry",
  "consolidatedAsOf": "2026-06-30",
  "sourceUrl": "https://publications.europa.eu/resource/consolidation/2019R1793%2F2026-06-30.ENG.xhtml",
  "watchlistItem": { "productKeyword": "betel leaves", "originCountry": "Bangladesh" },
  "matchState": "UNCHANGED",
  "changedFields": [],
  "checkedAt": "2026-10-08T11:27:31.749Z"
}
```

This is a real record from a live run against the current consolidated text: a 50%
physical/identity check frequency on betel leaves from Bangladesh, with both
special-condition footnotes resolved to their full text rather than left as a bare
superscript number.

### Change tracking across runs

Run this Actor on a schedule. Each watchlist item's last-seen snapshot (hazard,
frequency, special conditions) is stored per Actor, so every subsequent run reports
exactly what changed since the last one, not just the current state.

### Pricing

Pay per run started, plus per watchlist item checked (not per matched row - a single
item can legitimately match several annex rows, e.g. a broad keyword against several
CN codes under one country). See the Pricing tab for exact rates.

# Actor input Schema

## `watchlist` (type: `array`):

Commodity/origin-country combinations to check against Regulation (EU) 2019/1793's current consolidated annexes. Each item needs "originCountry" plus at least one of "cnCode" or "productKeyword". "cnCode" matches the published CN code (an "ex"-qualified annex entry is matched as a prefix in either direction). "productKeyword" matches case-insensitively against the published product description. If both are given on one item, both must match.

## Actor input object example

```json
{
  "watchlist": [
    {
      "cnCode": "1202 42 00",
      "originCountry": "Argentina"
    },
    {
      "productKeyword": "betel leaves",
      "originCountry": "Bangladesh"
    },
    {
      "cnCode": "1404 90 00",
      "originCountry": "India"
    }
  ]
}
```

# Actor output Schema

## `watchlistResults` (type: `string`):

Per-entry records.

# 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 = {
    "watchlist": [
        {
            "cnCode": "1202 42 00",
            "originCountry": "Argentina"
        },
        {
            "productKeyword": "betel leaves",
            "originCountry": "Bangladesh"
        },
        {
            "cnCode": "1404 90 00",
            "originCountry": "India"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("chosen_loafer/eu-food-import-monitor").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 = { "watchlist": [
        {
            "cnCode": "1202 42 00",
            "originCountry": "Argentina",
        },
        {
            "productKeyword": "betel leaves",
            "originCountry": "Bangladesh",
        },
        {
            "cnCode": "1404 90 00",
            "originCountry": "India",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("chosen_loafer/eu-food-import-monitor").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 '{
  "watchlist": [
    {
      "cnCode": "1202 42 00",
      "originCountry": "Argentina"
    },
    {
      "productKeyword": "betel leaves",
      "originCountry": "Bangladesh"
    },
    {
      "cnCode": "1404 90 00",
      "originCountry": "India"
    }
  ]
}' |
apify call chosen_loafer/eu-food-import-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,chosen_loafer/eu-food-import-monitor"
        }
    }
}
```

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/aYq0BEPHmnwN3JJce/builds/aTl8JRkRhq27pTB4e/openapi.json
