oneapi
Sign in

Check VAT in VIES

Checks several intra-community VAT numbers in one call, through VIES. With your own number as the requester the consultation is official and gets a consultation number — the proof of exemption.

POST
https://oneapi.ro/api/identificatori/v1/vies

Request body

Sent as JSON in the request body (Content-Type: application/json) — not in the query string.

NameTypeDescriptionAccepted values
tvarequired list Minimum 1, maximum 50.
solicitantoptional text Minimum 4, maximum 20. max 20 car.
A Romanian number Request body
{
    "tva": [
        "RO17621339"
    ]
}
With proof of consultation Request body
{
    "tva": [
        "DE811234567"
    ],
    "solicitant": "RO17621339"
}
Two numbers at once Request body
{
    "tva": [
        "RO17621339",
        "RO6719278"
    ]
}

Query parameters

This route accepts no query parameters.

How it behaves

  • The body holds tva — a list of at most 50 codes — and, optionally, solicitant, the requester's own VAT number.
  • Three states, never two. valid, invalid and indisponibil. On an outage the answer is indisponibil, never valid: false — a service outage is not evidence that a company does not exist, and an ERP that conflates them voids real invoices.
  • A VIES outage is not a route error: the response stays HTTP 200 and the affected number comes back indisponibil with a motiv. Disguised outages count too: VIES sends MS_UNAVAILABLE or a maintenance page with HTTP 200 as well — those are NOT read as invalid.
  • Proof of consultation. VIES returns a consultation number only when it receives the requester's number. Without solicitant, you get the timestamp but numar_consultare is absent. With it, you have something to show at an audit.
  • Only valid results are cached, for 10 minutes, never the invalid ones: a number can become valid tomorrow, and a cached "invalid" would reject a real customer. The din_cache field says whether the answer is live or remembered, and consultat_la is the timestamp issued by VIES, not the time we replied. Requests carrying solicitant are never served from cache — proof must be fresh.
  • Codes outside the VIES system are rejected LOCALLY, without touching the Commission service. The prefix is not always the country's ISO code: Greece uses EL, and XI is Northern Ireland, which stayed in the EU VAT system for goods after Brexit.
  • The Commission service is slow and fails often. Hence a two-level rate limit (per user and global) and a circuit that opens after five consecutive failures — if VIES is down, we stop hitting it for a few minutes.

What it is for

  • Check a customer's VAT number at invoicing time, for reverse charge.
  • Re-check your intra-EU customer base periodically, in batches.
  • Obtain proof of consultation — timestamp and consultation number — for a tax audit.

Response structure

All fields below live inside data.

FieldTypeDescription
inregistrari integer How many codes were checked.
sumar object How many came back valid, invalid and unavailable.
sumar.valid integer
sumar.invalid integer
sumar.indisponibil integer
rezultate[].cod string Code from the source code list — the key you filter on.
rezultate[].tara string The country the value refers to.
rezultate[].numar string Number of items counted.
rezultate[].stare string valid, invalid or indisponibil.
rezultate[].denumire string The name returned by the member state, where it publishes one.
rezultate[].adresa string The address returned by the member state, where it publishes one.
rezultate[].consultat_la string The timestamp issued by VIES, not the time of our reply.
rezultate[].din_cache boolean Whether the answer came from cache (only valid results are stored).
observatie null Appears when some codes could not be checked.
rezultate[].motiv The cause, where there is one. On a local invalid: format, in_afara_ue. On indisponibil: stat_membru_indisponibil (the member state database is not answering), aglomerat (busy), timeout, conexiune (connection failed), http_, raspuns_neinteligibil (a 200 without a verdict), circuit_deschis, throttled_user, throttled_global, solicitant_nerecunoscut (VIES does not recognise the number in solicitant).
rezultate[].explicatie The same cause, in words.
rezultate[].numar_consultare The consultation number, present only when you sent solicitant.

Response examples

body: {"tva": ["RO17621339"]}

POSThttps://oneapi.ro/api/identificatori/v1/vies
{
    "data": {
        "inregistrari": 1,
        "sumar": {
            "valid": 1,
            "invalid": 0,
            "indisponibil": 0
        },
        "rezultate": [
            {
                "cod": "RO17621339",
                "tara": "RO",
                "numar": "17621339",
                "stare": "valid",
                "denumire": "DANCO EXPRESS S.R.L.",
                "adresa": "MUNICIPIUL  BUCUREŞTI, SECTOR 2 00000 ŞOS. PANTELIMON Nr. 84 Bl. 409B Sc. A Ap. 2",
                "consultat_la": "2026-10-06T20: 39: 55.753Z",
                "din_cache": false
            }
        ],
        "observatie": null
    }
}

Error codes

CodeSlugWhen it occurs
401neautentificatToken missing, invalid, expired or revoked.
403feature_indisponibilThe current plan does not include the feature the route depends on.
422validaretva is missing, or there are more than 50 codes.
429cota_depasitaThe plan's monthly quota has been exceeded (see 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": "tva is missing, or there are more than 50 codes."
    }
}