# EU EORI Validator — Customs Number Check (`sourcerow/eu-eori-validator`) Actor

Check EORI customs numbers against the European Commission's official service — valid or not, plus the trader's registered name and address. You only pay for numbers actually checked.

- **URL**: https://apify.com/sourcerow/eu-eori-validator.md
- **Developed by:** [SourceRow](https://apify.com/sourcerow) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$6.00 / 1,000 eori 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?

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

Check EORI customs numbers against the European Commission's own validation
service. Returns valid or invalid, plus the registered trader name and address.
Numbers the service could not answer are not charged.

### What it does

An EORI number identifies anyone moving goods across an EU border. This Actor
queries the official validation service of the European Commission, the same one
behind the public EORI checker, and returns one row per number with 15 fields on
every row.

Where a number is valid, the service also returns the registered trader name and
address. That is more than VIES gives for VAT numbers, where most member states
withhold the name.

Results are matched back to the number that was asked, not to the position in
the response. The service answers in batches, and if one answer were missing,
reading results in order would shift every subsequent verdict onto the wrong
number.

### What you get

15 fields per row: `input`, `eori`, `country_prefix`, `result`, `name`,
`street`, `postal_code`, `city`, `country`, `checked_on`, `error`, `source_url`,
`licence`, `retrieved_at`, `issues`.

`result` is `valid`, `invalid`, or `unchecked`. The third means the Commission's
service did not answer, which is not the same as the number being bad.

### Input

| Field | Meaning |
|---|---|
| `eoriNumbers` | Numbers to check. Spaces, dots and dashes are normalised. |
| `eoriNumbersText` | A pasted list instead, one per line or comma-separated. |
| `maxNumbers` | Stop after this many. `0` removes the cap. |

```json
{
  "eoriNumbersText": "IT00159560366\nDE123456789\nFR41234567890",
  "maxNumbers": 100
}
```

### Sample output

One complete record:

```json
{
  "input": "IT00159560366",
  "eori": "IT00159560366",
  "country_prefix": "IT",
  "result": "valid",
  "name": "FERRARI S.P.A.",
  "street": "VIA EMILIA EST 1163",
  "postal_code": "41122",
  "city": "MODENA",
  "country": "Italy",
  "checked_on": "2026-08-28",
  "error": null,
  "source_url": "https://ec.europa.eu/taxation_customs/dds2/eos/",
  "licence": "European Commission EOS validation service",
  "retrieved_at": "2026-08-28T14:20:03Z",
  "issues": ""
}
```

### Pricing

| Event | Per 1,000 | Notes |
|---|---|---|
| EORI checked | $6.00 | Only numbers the service actually answered |

Rows marked `unchecked` are not charged. There is no start fee and no per-row
dataset fee.

### What it does not do

**It does not confirm what a business is allowed to import or export.** An EORI
number identifies the operator. Licences, authorisations and prohibitions are a
separate matter handled by the customs authority.

**It is not a VAT check.** Many EORI numbers are derived from a VAT number, but
a company can hold one without the other. For VAT registration status, use a
VIES check.

**No history.** The service answers about the number today. It does not say when
the number was issued or whether it was previously held by someone else.

**Unchecked rows are not retried automatically.** Re-run them rather than
treating them as invalid.

### Notes

`country_prefix` is taken from the number itself, so it is present even on
invalid numbers. A whole batch showing an unexpected prefix usually means the
list was typed in the wrong national format.

`issues` flags `valid_without_name` on numbers the service confirms but declines
to name. The number is good; the identity was not returned.

Nothing is cached between runs. Every run queries the Commission's service
directly, so a number revoked yesterday shows as invalid today.

### Support

Open the **Issues** tab with the specific EORI number and the `result` and
`error` values from the row.

### Licence and attribution

Numbers are validated against the EOS service of the European Commission. The
service is queried in real time; no dataset is downloaded, stored or
redistributed.

# Actor input Schema

## `eoriNumbers` (type: `array`):

Customs identification numbers to check, e.g. IT00159560366. Spaces, dots and dashes are cleaned up for you.

## `eoriNumbersText` (type: `string`):

Paste a list here instead of the field above. One per line or comma-separated.

## `maxNumbers` (type: `integer`):

Stop after this many. **0 removes the cap.**

## Actor input object example

```json
{
  "eoriNumbers": [
    "IT00159560366",
    "DE123456789",
    "FR41234567890"
  ],
  "maxNumbers": 100
}
```

# 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 = {
    "eoriNumbers": [
        "IT00159560366",
        "DE123456789",
        "FR41234567890"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("sourcerow/eu-eori-validator").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 = { "eoriNumbers": [
        "IT00159560366",
        "DE123456789",
        "FR41234567890",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("sourcerow/eu-eori-validator").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 '{
  "eoriNumbers": [
    "IT00159560366",
    "DE123456789",
    "FR41234567890"
  ]
}' |
apify call sourcerow/eu-eori-validator --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sourcerow/eu-eori-validator"
        }
    }
}

```

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/wfkdxYrF8hIp7rfow/builds/GotMA4Pf4nkb0rihp/openapi.json
