oneapi
Autentificare

Verifică TVA în VIES

Verifică mai multe coduri de TVA intracomunitare într-un apel, prin VIES. Cu codul tău ca solicitant, consultarea e oficială şi primeşte număr de consultare — dovada scutirii.

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

Corpul cererii

Se trimite ca JSON, în corpul cererii (Content-Type: application/json) — nu în şirul de interogare.

NumeTipDescriereValori acceptate
tvaobligatoriu listă Minim 1, maxim 50.
solicitantopțional text Minim 4, maxim 20. max 20 car.
Un cod românesc Corpul cererii
{
    "tva": [
        "RO17621339"
    ]
}
Cu dovada consultării Corpul cererii
{
    "tva": [
        "DE811234567"
    ],
    "solicitant": "RO17621339"
}
Două coduri deodată Corpul cererii
{
    "tva": [
        "RO17621339",
        "RO6719278"
    ]
}

Parametri de interogare

Ruta nu acceptă parametri de interogare.

Cum se comportă

  • Corpul are tva — o listă de cel mult 50 de coduri — și, opțional, solicitant, codul propriu al celui care întreabă.
  • Trei stări, niciodată două. valid, invalid și indisponibil. La indisponibilitate se întoarce indisponibil, niciodată valid: false — un serviciu picat nu e o dovadă că firma nu există, iar un ERP care le confundă anulează facturi pe bune.
  • Pana VIES nu e o eroare a rutei: răspunsul rămâne HTTP 200, iar codul afectat iese indisponibil cu motiv. Contează şi penele „deghizate”: VIES trimite MS_UNAVAILABLE ori o pagină de mentenanţă tot cu HTTP 200 — acelea NU sunt citite ca invalid.
  • Dovada consultării. VIES întoarce un număr de consultare doar când primește codul solicitantului. Fără solicitant, primești marca de timp dar numar_consultare lipsește. Cu el, ai ce prezenta la control.
  • Cache doar pe rezultatele valide, 10 minute, și niciodată pe cele invalide: un cod poate deveni valid mâine, iar un „invalid" ținut în cache ar respinge un client real. Câmpul din_cache spune dacă răspunsul e live sau memorat, iar consultat_la e marca de timp emisă de VIES, nu ora la care am răspuns noi. Cererile cu solicitant nu se servesc niciodată din cache — dovada trebuie să fie proaspătă.
  • Codurile din afara sistemului VIES sunt respinse LOCAL, fără să lovim serviciul Comisiei. Prefixul nu e mereu codul ISO al țării: Grecia folosește EL, iar XI e Irlanda de Nord, rămasă în sistemul TVA al UE pentru bunuri după Brexit.
  • Serviciul Comisiei e lent și pică des. De aceea avem ritm pe două niveluri (per utilizator și global) și un circuit care se închide după cinci eșecuri consecutive — dacă VIES e căzut, nu-l mai lovim câteva minute.

La ce folosește

  • Verifici codul de TVA al unui client la momentul emiterii facturii, pentru taxare inversă.
  • Reverifici periodic baza de clienți intracomunitari, în loturi.
  • Obții dovada consultării — marca de timp și numărul de consultare — pentru un control fiscal.

Structura răspunsului

Toate câmpurile de mai jos sunt în data.

CâmpTipDescriere
inregistrari integer Câte coduri s-au verificat.
sumar object Câte au ieșit valide, invalide și indisponibile.
sumar.valid integer
sumar.invalid integer
sumar.indisponibil integer
rezultate[].cod string Codul din nomenclatorul sursei — cheia pe care se filtrează.
rezultate[].tara string Ţara la care se referă valoarea.
rezultate[].numar string Numărul de elemente numărate.
rezultate[].stare string valid, invalid sau indisponibil.
rezultate[].denumire string Denumirea returnată de statul membru, unde o publică.
rezultate[].adresa string Adresa returnată de statul membru, unde o publică.
rezultate[].consultat_la string Marca de timp emisă de VIES, nu ora răspunsului nostru.
rezultate[].din_cache boolean Dacă răspunsul vine din cache (doar rezultatele valide se memorează).
observatie null Apare când unele coduri n-au putut fi verificate.
rezultate[].motiv Cauza, unde există. La invalid local: format, in_afara_ue. La indisponibil: stat_membru_indisponibil (baza statului membru nu răspunde), aglomerat, timeout, conexiune, http_<cod>, raspuns_neinteligibil (un 200 fără verdict), circuit_deschis, throttled_user, throttled_global, solicitant_nerecunoscut (VIES nu recunoaşte codul din solicitant).
rezultate[].explicatie Aceeași cauză, în cuvinte.
rezultate[].numar_consultare Numărul de consultare, prezent doar când ai trimis solicitant.

Exemple de răspuns

corp: {"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
    }
}

Coduri de eroare

CodSlugCând apare
401neautentificatToken lipsă, invalid, expirat sau revocat.
403feature_indisponibilPlanul curent nu include funcţia de care ţine ruta.
422validareLipsește tva, sau sunt peste 50 de coduri.
429cota_depasitaCota lunară a planului a fost depăşită (vezi Retry-After).

Toate erorile au aceeași formă. eroare.cod e stabil și e cel după care trebuie să ramifici în cod — nu după textul din mesaj, care se poate schimba.

{
    "eroare": {
        "cod": "validare",
        "mesaj": "Lipsește tva, sau sunt peste 50 de coduri."
    }
}