oneapi
Autentificare
Financiar v1 / Validare

Validare cod de TVA

Verifică structura unui cod de TVA din UE (28 de state) şi, pentru codurile româneşti, întoarce
statutul fiscal de la ANAF: plătitor de TVA, TVA la încasare, inactivitate fiscală, e-Factura.

Structura validă nu înseamnă că firma există. Pentru celelalte state membre verificăm doar
forma numărului; existenţa se confirmă la VIES.

Plătitor de TVA în România NU e acelaşi lucru cu valid în VIES pentru operaţiuni
intracomunitare — sunt registre diferite, iar răspunsul o spune explicit.

POST
https://oneapi.ro/api/financiar/v1/validare/tva

Corpul cererii

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

NumeTipDescriereValori acceptate
codobligatoriu string Obligatoriu, în corpul cererii. Cu sau fără prefix de ţară; separatorii se ignoră. max 20 car.
Cod de TVA românesc Corpul cererii
{
    "cod": "RO14399840"
}
Fără prefixul de ţară Corpul cererii
{
    "cod": "14399840"
}
Cu separator în mijloc Corpul cererii
{
    "cod": "RO 6719278"
}
Cod prea scurt Corpul cererii
{
    "cod": "RO1"
}

Parametri de interogare

Ruta nu acceptă parametri de interogare.

Cum se comportă

  • Verifică structura unui cod de TVA din Uniunea Europeană (28 de state, inclusiv XI pentru Irlanda de Nord) şi, pentru codurile româneşti, întoarce statutul fiscal din registrul ANAF.
  • Structura validă nu înseamnă că firma există. Pentru statele membre altele decât România verificăm doar forma numărului — cifra de control naţională diferă de la stat la stat şi nu o calculăm. La codurile româneşti se verifică şi cifra de control a CUI-ului (cheia ANAF 753217532), deci o cifră greşită dă structura_valida: false. Existenţa se confirmă la VIES.
  • Plătitor de TVA în România NU e acelaşi lucru cu valid în VIES pentru operaţiuni intracomunitare. Sunt registre diferite. Cine ia platitor_tva: true ca temei pentru o livrare intracomunitară scutită greşeşte: acolo e nevoie de verificare VIES, cu număr de consultare. Răspunsul repetă avertismentul la fiecare cerere, în meta.atentie_intracomunitar.
  • fiscal.stare_la_data e data pentru care ANAF a confirmat starea, NU momentul importului nostru. E per-firmă: la un refresh parţial, fiecare firmă îşi poartă data ei.
  • inactiv_fiscal merită atenţie specială: facturile emise către un contribuabil declarat inactiv au regim fiscal special. Când e true, nota din răspuns o semnalează explicit.
  • Absenţa statutului fiscal (motiv_fiscal: "fara_stare_fiscala") NU înseamnă că firma nu e plătitoare de TVA — înseamnă că nu avem informaţia pentru acel CUI.
  • Codul se acceptă cu sau fără prefix de ţară: RO14399840 sau 14399840. Fără prefix se presupune România — cazul dominant, iar niciun alt cod de TVA din UE nu circulă fără litere. Presupunerea se raportează în tara_presupusa, ca să fie vizibilă.
  • Grecia are prefixul EL în sistemul TVA, nu GR. Ambele se acceptă la intrare şi se normalizează la EL.
  • Nu se întoarce split_tva: măsura a fost abrogată în 2020, iar câmpul e false la toate înregistrările. Un câmp mereu fals e zgomot.

La ce folosește

  • Verificarea unui partener înainte de a emite o factură.
  • Depistarea contribuabililor inactivi fiscal.
  • Verificarea dacă un partener aplică TVA la încasare.

Structura răspunsului

CâmpTipDescriere
data[] object[]
meta[] string[] Plicul răspunsului: sursa, prospeţimea şi precizările care însoţesc datele.
data.tara string Prefixul de ţară normalizat (EL pentru Grecia).
data.tara_presupusa boolean true când codul a venit fără prefix şi s-a presupus România.
data.structura_valida boolean Forma numărului corespunde statului; la România şi cifra de control a CUI-ului. Nu atestă existenţa firmei.
data.fiscal.platitor_tva boolean Înregistrat în scopuri de TVA în România, potrivit ANAF.
data.fiscal.tva_la_incasare boolean Aplică sistemul TVA la încasare — schimbă momentul exigibilităţii.
data.fiscal.inactiv_fiscal boolean Declarat inactiv fiscal. Facturile către un inactiv au regim special.
data.fiscal.e_factura boolean Înregistrat în registrul RO e-Factura, cu data înregistrării.
data.fiscal.stare_la_data string Data pentru care ANAF a confirmat starea.
data.motiv_fiscal null doar_pentru_romania sau fara_stare_fiscala. Absent când structura e invalidă — acolo structura_valida e deja explicaţia.

Exemple de răspuns

body: {"cod": "RO14399840"}

POSThttps://oneapi.ro/api/financiar/v1/validare/tva
{
    "data": {
        "cod": "RO14399840",
        "tara": "RO",
        "tara_presupusa": false,
        "numar": "14399840",
        "structura_valida": true,
        "fiscal": {
            "platitor_tva": true,
            "tva_de_la": "2002-02-01",
            "tva_pana_la": null,
            "tva_la_incasare": false,
            "tva_la_incasare_de_la": null,
            "inactiv_fiscal": false,
            "data_inactivare": null,
            "data_reactivare": null,
            "e_factura": false,
            "e_factura_de_la": null,
            "data_radiere": null,
            "stare_la_data": "2026-08-16"
        },
        "motiv_fiscal": null
    },
    "meta": {
        "temei": "structura numărului de TVA pentru cele 28 de state (la România şi cifra de control a CUI-ului, cheia 753217532); statutul fiscal din registrul ANAF.",
        "sursa_fiscal": "ANAF — registrul plătitorilor de TVA",
        "atentie_intracomunitar": "Statutul de plătitor de TVA în România nu atestă valabilitatea codului pentru operaţiuni intracomunitare: sunt registre diferite. Pentru livrări intracomunitare scutite e nevoie de verificare VIES, cu număr de consultare.",
        "nota": "Statut fiscal preluat din registrul ANAF, la data din `stare_la_data`."
    }
}

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 cod sau are o lungime imposibilă. Un cod prezent dar greşit întoarce 200 cu structura_valida: false.
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 cod sau are o lungime imposibilă. Un cod prezent dar greşit întoarce 200 cu structura_valida: false."
    }
}