oneapi
Sign in
Financiar v1 / Validare

VAT number validation

Checks the structure of an EU VAT number (28 states) and, for Romanian numbers, returns the tax status from ANAF: VAT-registered, VAT on collection, tax inactivity, e-invoicing.

A valid structure does not mean the company exists. For the other member states we check only the form of the number (for Romania, the CUI check digit too); existence is confirmed at VIES.

Being VAT-registered in Romania is NOT the same as being valid in VIES for intra-Community operations — they are different registers, and the response says so explicitly.

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

Request body

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

NameTypeDescriptionAccepted values
codrequired string Required, in the request body. With or without a country prefix; separators are ignored. max 20 car.
Romanian VAT number Request body
{
    "cod": "RO14399840"
}
Without the country prefix Request body
{
    "cod": "14399840"
}
With a separator inside Request body
{
    "cod": "RO 6719278"
}
Code too short Request body
{
    "cod": "RO1"
}

Query parameters

This route accepts no query parameters.

How it behaves

  • Checks the structure of an EU VAT number (28 states, including XI for Northern Ireland) and, for Romanian numbers, returns the tax status from the ANAF register.
  • A valid structure does not mean the company exists. For member states other than Romania we check only the shape of the number — the national check digit differs from state to state and we do not compute it. For Romanian numbers the CUI check digit is verified too (ANAF key 753217532), so a wrong digit gives structura_valida: false. Existence is confirmed through VIES.
  • Being VAT-registered in Romania is NOT the same as being valid in VIES for intra-Community transactions. They are different registers. Taking platitor_tva: true as grounds for an exempt intra-Community supply is a mistake: that requires a VIES check, with a consultation number. The response repeats the warning on every request, in meta.atentie_intracomunitar.
  • fiscal.stare_la_data is the date for which ANAF confirmed the status, NOT the time of our import. It is per company: on a partial refresh, each company carries its own date.
  • inactiv_fiscal deserves particular attention: invoices issued to a taxpayer declared inactive have a special tax regime. When it is true, the note in the response flags it explicitly.
  • A missing tax status (motiv_fiscal: "fara_stare_fiscala") does NOT mean the company is not VAT-registered — it means we do not have the information for that tax code.
  • The code is accepted with or without the country prefix: RO14399840 or 14399840. Without a prefix Romania is assumed — the dominant case, and no other EU VAT number circulates without letters. The assumption is reported in tara_presupusa, so it stays visible.
  • Greece uses the prefix EL in the VAT system, not GR. Both are accepted on input and normalised to EL.
  • split_tva is not returned: the measure was repealed in 2020 and the field is false on every record. A field that is always false is noise.

What it is for

  • Checking a business partner before issuing an invoice.
  • Spotting taxpayers declared inactive.
  • Checking whether a partner uses VAT on collection.

Response structure

FieldTypeDescription
data[] object[]
meta[] string[] The response envelope: the source, the freshness and the notes that go with the data.
data.tara string The normalised country prefix (EL for Greece).
data.tara_presupusa boolean true when the code arrived without a prefix and Romania was assumed.
data.structura_valida boolean The shape of the number matches that state; for Romania, the CUI check digit too. It does not attest that the company exists.
data.fiscal.platitor_tva boolean Registered for VAT purposes in Romania, per ANAF.
data.fiscal.tva_la_incasare boolean Uses the VAT-on-collection system — this changes when VAT becomes chargeable.
data.fiscal.inactiv_fiscal boolean Declared inactive for tax purposes. Invoices to an inactive taxpayer have a special regime.
data.fiscal.e_factura boolean Listed in the RO e-Factura register, with the registration date.
data.fiscal.stare_la_data string The date for which ANAF confirmed the status.
data.motiv_fiscal null doar_pentru_romania or fara_stare_fiscala. Absent when the structure is invalid — there structura_valida is already the explanation.

Response examples

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`."
    }
}

Error codes

CodeSlugWhen it occurs
401neautentificatToken missing, invalid, expired or revoked.
403feature_indisponibilThe current plan does not include the feature the route depends on.
422validarecod missing or of an impossible length. A code that is present but wrong returns 200 with structura_valida: false.
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": "cod missing or of an impossible length. A code that is present but wrong returns 200 with structura_valida: false."
    }
}