EORI validation
Checks an EORI number — the customs identifier used on declarations with third countries — through the European Commission's service.
It has nothing to do with intra-Community operations: there the VAT number is used, checked through VIES. The confusion is easy and costly.
There is no local list of EORI numbers and it cannot be derived from the tax id: the number is obtained through a separate registration with customs, which only those who declare at customs do. So every unknown check is an external call, protected by a rate limit and a circuit breaker.
Request body
Sent as JSON in the request body (Content-Type: application/json) — not in the query string.
{
"eori": "RO14399840"
}
{
"eori": "RO 14399840"
}
{
"eori": "DE123456789012345"
}
{
"eori": "XX1"
}
Query parameters
How it behaves
- Validates an EORI number through the European Commission service (DDS2/EOS).
- EORI is a CUSTOMS identifier, for declarations involving third countries — it has nothing to do with intra-Community transactions. Those use the VAT number, checked through VIES. The confusion is easy and costly: someone searching for "European partner validation" lands here and checks the wrong thing.
- There is no local list and it cannot be derived from the tax code. The number is obtained through a separate registration with customs, done only by those who file customs declarations — most companies never do. So a valid, active, VAT-registered tax code says nothing about the existence of an EORI. Every unknown check is an external call.
- The structure for Romania has three forms, depending on the holder (Norms of ANAF Order 1886): a legal entity established in Romania →
RO+ tax code; a natural person established in Romania →RO+ personal numeric code; an operator established in a third country →RO+ the ISO code of that state + the number from that state. The national part may be alphanumeric, up to 15 characters. - Hence the method is
POST: an EORI of a natural person IS a personal numeric code with a prefix, so the number may be personal data and has no place in a query string. - Three states, not two.
validandinvalidcome from the Commission;serviciu_indisponibilmeans we received no verdict, andvalidisnull, notfalse. Treating an outage as "invalid number" would make a client refuse a perfectly legitimate partner. - A Commission outage is not a route error. The response stays HTTP 200, with
stare: serviciu_indisponibilandmotivsays why:timeout,conexiune(connection failed),http_,raspuns_neinteligibil(a 200 without a verdict — usually the maintenance page),circuit_deschis(after repeated failures we stop calling for a while;meta.reia_dupa_ssays how long). An outage is never cached, and a 200 from the Commission without a SOAP envelope is not read as a verdict. - Name and address are published only if the economic operator has consented. A valid EORI without a name is normal, not an incomplete answer — and the response says so explicitly.
provenientashows whether the answer came from cache, from the local structure check, or from the Commission.
What it is for
- Checking a partner before filling in a customs declaration.
- Confirming your own EORI number.
Response structure
true/false from the Commission, or null when the service gave no verdict.
valid, invalid, structura_invalida, serviciu_indisponibil.
null otherwise.
serviciu_indisponibil: timeout, conexiune, http_, raspuns_neinteligibil, circuit_deschis. null otherwise.
cache, local, extern or circuit (no call: the circuit breaker is open).
Response examples
body: {"eori": "RO14399840"}
{
"data": {
"eori": "RO14399840",
"valid": true,
"stare": "valid",
"detaliu": "Valid",
"denumire": null,
"adresa": null,
"motiv": null,
"provenienta": "extern"
},
"meta": {
"sursa": "Comisia Europeană — serviciul de validare EORI (DDS2/EOS).",
"temei": "Numărul EORI e atribuit de autoritatea vamală; pentru România, de Direcţia Generală a Vămilor din ANAF.",
"provenienta": "Apel la serviciul Comisiei.",
"atentie_denumire": "Numărul e valid, dar denumirea şi adresa lipsesc: se publică numai dacă operatorul economic şi-a dat consimţământul. Absenţa lor nu e un răspuns incomplet.",
"nota_intracomunitar": "EORI e identificator VAMAL, pentru operaţiuni cu ţări terţe. Pentru valabilitatea unui cod de TVA în operaţiuni intracomunitare, verificarea se face la VIES."
}
}
body: {"eori": "RO 14399840"}
{
"data": {
"eori": "RO14399840",
"valid": true,
"stare": "valid",
"detaliu": "Valid",
"denumire": null,
"adresa": null,
"motiv": null,
"provenienta": "cache"
},
"meta": {
"sursa": "Comisia Europeană — serviciul de validare EORI (DDS2/EOS).",
"temei": "Numărul EORI e atribuit de autoritatea vamală; pentru România, de Direcţia Generală a Vămilor din ANAF.",
"provenienta": "Răspuns din cache — nu s-a făcut apel extern.",
"atentie_denumire": "Numărul e valid, dar denumirea şi adresa lipsesc: se publică numai dacă operatorul economic şi-a dat consimţământul. Absenţa lor nu e un răspuns incomplet.",
"nota_intracomunitar": "EORI e identificator VAMAL, pentru operaţiuni cu ţări terţe. Pentru valabilitatea unui cod de TVA în operaţiuni intracomunitare, verificarea se face la VIES."
}
}
body: {"eori": "DE123456789012345"}
{
"data": {
"eori": "DE123456789012345",
"valid": false,
"stare": "invalid",
"detaliu": "Not valid",
"denumire": null,
"adresa": null,
"motiv": null,
"provenienta": "extern"
},
"meta": {
"sursa": "Comisia Europeană — serviciul de validare EORI (DDS2/EOS).",
"temei": "Numărul EORI e atribuit de autoritatea vamală; pentru România, de Direcţia Generală a Vămilor din ANAF.",
"provenienta": "Apel la serviciul Comisiei.",
"nota_intracomunitar": "EORI e identificator VAMAL, pentru operaţiuni cu ţări terţe. Pentru valabilitatea unui cod de TVA în operaţiuni intracomunitare, verificarea se face la VIES."
}
}
body: {"eori": "XX1"}
{
"data": {
"eori": "XX1",
"valid": false,
"stare": "invalid",
"detaliu": "Not valid",
"denumire": null,
"adresa": null,
"motiv": null,
"provenienta": "extern"
},
"meta": {
"sursa": "Comisia Europeană — serviciul de validare EORI (DDS2/EOS).",
"temei": "Numărul EORI e atribuit de autoritatea vamală; pentru România, de Direcţia Generală a Vămilor din ANAF.",
"provenienta": "Apel la serviciul Comisiei.",
"nota_intracomunitar": "EORI e identificator VAMAL, pentru operaţiuni cu ţări terţe. Pentru valabilitatea unui cod de TVA în operaţiuni intracomunitare, verificarea se face la VIES."
}
}
Error codes
| Code | Slug | When it occurs |
|---|---|---|
| 401 | neautentificat | Token missing, invalid, expired or revoked. |
| 403 | feature_indisponibil | The current plan does not include the feature the route depends on. |
| 422 | validare | eori missing or of an impossible length. A number that is present but malformed returns 200 with stare: "structura_invalida". |
| 429 | limita_ta | You exceeded your rate for external checks; capacitate_serviciu — the service is at capacity, not a limit on your account. Both with Retry-After. |
All errors share the same shape. eroare.cod is stable and is the value you should branch on in code — not the text in mesaj, which may change.
{
"eroare": {
"cod": "validare",
"mesaj": "eori missing or of an impossible length. A number that is present but malformed returns 200 with stare: \"structura_invalida\"."
}
}