# EUDR Checker - HS Code Scope & Country Risk (Deforestation) (`atlasdata/eudr-scope-risk-checker-reliable`) Actor

EUDR checker: does an HS/CN code fall under the EU Deforestation Regulation (Annex I of 2023/1115, consolidated 18 Sep 2026), and what is the country's risk level under Implementing Reg. 2025/1093? Versioned official tables, citations, dates.

- **URL**: https://apify.com/atlasdata/eudr-scope-risk-checker-reliable.md
- **Developed by:** [Christian Machon](https://apify.com/atlasdata) (community)
- **Categories:** Business, Developer tools, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 line 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

## EUDR Checker - HS Code Scope & Country Risk (Deforestation)

**EUDR checker for the EU Deforestation Regulation: is an HS/CN code in scope, and what risk level does the country of production have? $0.50 per 1,000 lines.**

Check, in one call, whether a product **HS / CN / TARIC code** is covered by the **EU Deforestation Regulation (EUDR, Regulation (EU) 2023/1115)** and what **risk level** its **country of production** has under **Commission Implementing Regulation (EU) 2025/1093**. You get the commodity (cattle, cocoa, coffee, oil palm, rubber, soya, wood), the exact Annex I entry with its official description and exclusions, the due-diligence regime (simplified / full / high scrutiny), the date your obligations apply, and the citation for every answer.

The official tables are **bundled and versioned inside the Actor**: no website is scraped on each run, so it is fast (about 1-2 s), deterministic and polite to EU servers. Every result says which dataset version and source dates it used.

> ⚠️ **Not legal advice. Not legally binding.** This tool is an informational aid compiled from EU legal texts. Only the texts published in the *Official Journal of the European Union* are authentic. The consolidated text used is itself "a documentation tool with no legal effect". Customs classification and EUDR obligations must be confirmed with your customs authority, EUDR competent authority or counsel. Atlas Data accepts no liability for decisions based on this output.

### What it does

- **Scope (Annex I).** It matches your code against all 93 Annex I entries of Regulation (EU) 2023/1115 as consolidated on **18 September 2026**, which includes:
  - Regulation (EU) 2024/3234 (the 12-month delay),
  - Regulation (EU) 2025/2650 (the simplification; it removed printed products of chapter 49),
  - Commission Delegated Regulation (EU) 2026/2102 (the new Annex I list: e.g. frozen cattle tongues, coffee extracts, palm-based oleochemicals, soaps and wooden seats; several entries only apply from **30 Dec 2027**).
- **Country risk (2025/1093).** There are 140 low-risk countries and 4 high-risk countries (Belarus, North Korea, Myanmar, Russia). Every other country is **standard risk** (Art. 1(2)). All 249 ISO 3166 countries are bundled, and names, alpha-2 and alpha-3 codes are accepted.
- **Due diligence.**
  - Low risk: simplified due diligence is possible (Art. 13).
  - Standard risk: full due diligence (Arts. 9-11).
  - High risk: full due diligence with high scrutiny (9 % check rate, Art. 16(9)).
  - Downstream operators and traders get their Art. 5 duties.
  - Micro or small primary operators in low-risk countries get a hint about the Art. 4a simplified declaration.
- **Application date.**
  - The general date is 30 Dec 2026.
  - Micro or small operators established by 31 Dec 2024 start on 30 Jun 2027 (Art. 38(3)). The exception is timber products already covered by the old EU Timber Regulation (995/2010), which are flagged as `eutrProduct`.

#### Scope statuses

| `scopeStatus` | Meaning |
|---|---|
| `in_scope` | The whole code is listed in Annex I. |
| `in_scope_if_description_matches` | Listed as an **"ex"** code: only goods matching the Annex description are covered (e.g. "of cattle", "synthesized using oil palm", "of wood"; used/second-hand wood products are excluded). |
| `partially_in_scope` | Your code is broader than the listed subheadings (e.g. `1201` where only `1201 90 00` is listed). Send a longer code. |
| `scheduled` | Added by 2026/2102 but not yet applicable on your `referenceDate` (see `scopeStartsOn`). |
| `not_in_scope` | Not listed in Annex I. |

### Input

| Field | Type | Description |
|---|---|---|
| `mode` | `check` | `listProducts` | `listCountries` | `check` (default) classifies your lines. The list modes dump the full bundled tables. |
| `codes` | string\[] | `"CODE|COUNTRY"` per line, e.g. `"1801 00 00|CI"`. Spaces and dots are allowed, with 2-10 digits. |
| `items` | object\[] | `{"id","code","country","description"}`. The keys `hsCode`, `cnCode` and `countryOfProduction` also work. |
| `country` | string | The default country for lines without one. |
| `role` | `operator` | `downstream_operator` | `trader` | The default is `operator`. |
| `companySize` | `large_or_medium` | `micro_or_small` | `unknown` | Used for the application date. |
| `referenceDate` | `YYYY-MM-DD` | The date to evaluate on. The default is today (UTC). |
| `includeAnnexDetails` | boolean | Includes the Annex description and exclusions. The default is true. |
| `maxItems` | integer | 1-5000; the default is 1000. |

#### Example input

```json
{
  "codes": ["1801 00 00|CI", "4407 11|SE", "1511 10 90|Indonesia", "1201|BR",
            "0901 11 00|Vietnam", "4011 10|TH", "4403 21|Russia", "8703 80|DE"],
  "role": "operator",
  "companySize": "large_or_medium",
  "referenceDate": "2027-01-15"
}
```

### Output

Real output of the example above (platform run, 29 Oct 2026):

| Code | Country | Commodity | Scope | Risk | Due diligence | Applies from |
|---|---|---|---|---|---|---|
| `1801 00 00` | CI | Cocoa | `in_scope` | standard | `full` | 2026-12-30 |
| `4407 11` | SE | Wood | `in_scope_if_description_matches` | low | `simplified_possible` | 2026-12-30 |
| `1511 10 90` | Indonesia | Oil palm | `in_scope_if_description_matches` | standard | `full` | 2026-12-30 |
| `1201` | BR | Soya | `partially_in_scope` | standard | `full` | 2026-12-30 |
| `0901 11 00` | Vietnam | Coffee | `in_scope` | low | `simplified_possible` | 2026-12-30 |
| `4011 10` | TH | Rubber | `in_scope_if_description_matches` | low | `simplified_possible` | 2026-12-30 |
| `4403 21` | Russia | Wood | `in_scope_if_description_matches` | high | `full_high_scrutiny` | 2026-12-30 |
| `8703 80` | DE | – | `not_in_scope` | low | `not_applicable` | – |

One full dataset item:

```json
{
  "id": null,
  "inputCode": "1511 10 90",
  "inputCountry": "Indonesia",
  "inputDescription": null,
  "code": "15111090",
  "codeFormatted": "1511 10 90",
  "status": "ok",
  "scopeStatus": "in_scope_if_description_matches",
  "inScope": true,
  "scopeExplanation": "Listed as an \"ex\" code in Annex I: only goods under this code that match the Annex I description (e.g. of cattle / made using oil palm / of wood) are relevant products.",
  "commodity": "Oil palm",
  "scopeStartsOn": null,
  "annexMatches": [
    {
      "commodity": "Oil palm",
      "annexCode": "ex 1511",
      "exCode": true,
      "description": "Palm oil and its fractions, whether or not refined, but not chemically modified",
      "exclusions": [
        "not including waste as defined in Article 3, point (1), of Directive 2008/98/EC"
      ],
      "appliesFrom": null
    }
  ],
  "countryIso2": "ID",
  "countryName": "Indonesia",
  "countryNameInRegulation": null,
  "countryRisk": "standard",
  "countryRiskSource": "Implementing Regulation (EU) 2025/1093",
  "dueDiligence": {
    "regime": "full",
    "text": "Standard-risk country: full due diligence - information (Art. 9), risk assessment (Art. 10) and risk mitigation (Art. 11) before submitting the DDS.",
    "checkRate": "at least 3% of operators, non-SME downstream operators and non-SME traders (Art. 16(8))"
  },
  "dueDiligenceRegime": "full",
  "role": "operator",
  "companySize": "large_or_medium",
  "obligationsApplyFrom": "2026-12-30",
  "obligationsApplyBasis": "Art. 38(2)",
  "obligationsApplyOnReferenceDate": true,
  "eutrProduct": false,
  "referenceDate": "2027-01-15",
  "notes": [
    "Not listed in the Annex of Implementing Regulation (EU) 2025/1093, so standard risk applies (Art. 1(2))."
  ],
  "dataset": {
    "version": "2026-10-29.1",
    "retrievedAt": "2026-10-29",
    "annexI": "02023R1115-20260918",
    "countryRisk": "32025R1093"
  }
}
```

The `OUTPUT` record in the key-value store holds the run summary: counts, the full dataset version block with source URLs, retrieval dates and SHA-256 hashes, the disclaimer and the attribution.

### Pricing (pay per event)

| Event | Price |
|---|---|
| Actor start | $0.00005 |
| Line checked (each valid line, or each row in the list modes) | $0.0005 |

So 1,000 lines cost about **$0.50**. Invalid codes are reported but **not charged**. A typical 10-line call costs about $0.005.

### Data sources, versions and citations

| Table | Legal source | Version used | Retrieved |
|---|---|---|---|
| Annex I relevant products | Regulation (EU) 2023/1115, consolidated text **02023R1115-20260918** (amended by 2024/3234, 2025/2650, Delegated Reg. 2026/2102). ELI: http://data.europa.eu/eli/reg/2023/1115/oj | 18 Sep 2026 consolidation | 2026-10-29 |
| Country risk | Commission Implementing Regulation (EU) **2025/1093** of 22 May 2025, in force since 26 May 2025. ELI: http://data.europa.eu/eli/reg_impl/2025/1093/oj | OJ L 2025/1093, 23.5.2025 | 2026-10-29 |
| EUTR products (date exception only) | Regulation (EU) No 995/2010, Annex. ELI: http://data.europa.eu/eli/reg/2010/995/oj | OJ L 295, 12.11.2010 | 2026-10-29 |

- The texts were downloaded once from the EU Publications Office (Cellar) and parsed into `src/eudr-data.json`. The source URLs and SHA-256 hashes are in every run's `OUTPUT.dataset`.
- The ISO 3166 mapping of country names was added by Atlas Data; the Regulation lists names only, e.g. "Congo" means the Republic of the Congo (CG) and "Solomon Island" means SB.
- Dataset version `2026-10-29.1`. When the Commission reviews the country list or amends Annex I, a new dataset version is published, and old results keep their version stamp.

**Attribution:** © European Union, https://eur-lex.europa.eu. The texts are reused under the Commission's reuse policy (Decision 2011/833/EU). This product is compiled and transformed by Atlas Data and is not an official EU publication.

### Limits and what is not included

- **No geolocation or deforestation check yet.** It does not check plots against the 31-12-2020 forest baseline. That is planned for v2, based on JRC GFC2020.
- It doesn't submit due-diligence statements to TRACES / the EUDR Information System.
- Sub-national risk classifications: none exist at present, and the Commission's list is national.
- Classification of your goods into a CN code is your responsibility. "ex" entries need a human check of the description.

### FAQ

**Is cocoa from Côte d'Ivoire low risk?** No. It is not listed in 2025/1093, so it is **standard** risk.

**Does EUDR apply to used wooden furniture?** No. The wood entries exclude used and second-hand products (see `exclusions`).

**Can AI agents call this?** Yes. Use run-sync-get-dataset-items and send `codes`. The responses are small, flat JSON.

# Actor input Schema

## `mode` (type: `string`):

check = classify your lines; listProducts = dump the whole bundled Annex I table; listCountries = dump all ISO countries with their 2025/1093 risk level.

## `codes` (type: `array`):

One line per product: HS/CN/TARIC code (2-10 digits, spaces/dots allowed), optionally followed by | and the country of production (ISO alpha-2, alpha-3 or English name).

## `items` (type: `array`):

Alternative structured input: \[{"id":"PO-1","code":"090111","country":"BR","description":"green coffee"}]. Keys hsCode/cnCode and countryOfProduction are also accepted.

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

Used for lines that do not name a country.

## `role` (type: `string`):

Determines which obligations are summarised (Art. 4 vs Art. 5).

## `companySize` (type: `string`):

Used for the application date (30 Dec 2026, or 30 Jun 2027 for micro/small operators established by 31 Dec 2024, except EUTR timber products).

## `referenceDate` (type: `string`):

Date to evaluate scope and application dates on. Default: today (UTC).

## `includeAnnexDetails` (type: `boolean`):

Adds the official Annex I description and exclusions to each matched line.

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

Upper limit of lines checked (and charged).

## Actor input object example

```json
{
  "mode": "check",
  "codes": [
    "1801 00 00|CI",
    "4407 11|SE",
    "1511 10 90|Indonesia",
    "1201|BR"
  ],
  "role": "operator",
  "companySize": "unknown",
  "includeAnnexDetails": true,
  "maxItems": 1000
}
```

# Actor output Schema

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

No description

## `table` (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 = {
    "codes": [
        "1801 00 00|CI",
        "4407 11|SE",
        "1511 10 90|Indonesia",
        "1201|BR"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("atlasdata/eudr-scope-risk-checker-reliable").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 = { "codes": [
        "1801 00 00|CI",
        "4407 11|SE",
        "1511 10 90|Indonesia",
        "1201|BR",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("atlasdata/eudr-scope-risk-checker-reliable").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 '{
  "codes": [
    "1801 00 00|CI",
    "4407 11|SE",
    "1511 10 90|Indonesia",
    "1201|BR"
  ]
}' |
apify call atlasdata/eudr-scope-risk-checker-reliable --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,atlasdata/eudr-scope-risk-checker-reliable"
        }
    }
}
```

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/zaT3ngPUFVAoLXFu8/builds/bKEvaiUHQXMHgGykh/openapi.json
