Anaf v1 / e-Factura
Validează factura
Verdictul pe trei straturi — XSD, regulile europene EN 16931 şi cele româneşti CIUS-RO — pentru o factură deja făcută. Fiecare eroare vine cu codul regulii, ca să ştii ce anume ai încălcat.
POST
https://oneapi.ro/api/anaf/v1/efactura/validate
Corpul cererii
Corpul cererii e documentul întreg, trimis brut (Content-Type: application/xml) — nu un obiect cu câmpuri.
Factură UBL CIUS-RO
Factură în CII
Factură corectată
Parametri de interogare
NumeTipDescriereValori acceptate
anafopțional
boolean
La
1 (sau validate=anaf) adaugă cross-check la validatorul ANAF; confirmarea apare în anaf_confirmation. Implicit, validare integral locală.
ex. 1
viesopțional
boolean
La
1 verifică în VIES codul de TVA al cumpărătorului non-RO; rezultatul apare în vies şi nu afectează valid. Apel extern opţional — dacă VIES nu răspunde, state: unavailable.
ex. 1
Cum se comportă
- Documentul se poate trimite şi ca fişier:
multipart/form-datacu câmpulfisier(curl -F fisier=@document.xml), în locul corpului brut. Conţinutul fişierului devine corpul cererii, deci rezultatul e identic; opţiunile rămân în query string, iar alt câmp de formular lângăfisierdă422 camp_necunoscut. - Primeşte XML-ul unei facturi în corpul cererii şi întoarce verdictul de validare pe trei straturi, cumulativ: (1) well-formed — XML-ul se parsează; (2) o verificare numerică proprie, care recalculează totalurile şi raportează diferenţa exactă acolo unde sumele nu se leagă; (3) Schematron-ul oficial EN 16931 + CIUS-RO + RO-eFactura, rulat local prin Saxon.
- Verificarea numerică proprie (stratul 2) e cea care prinde greşeala care doare cel mai des: un total care nu corespunde sumei liniilor. În loc de un simplu „invalid", răspunsul dă diferenţa exactă, ca să vezi dintr-o privire cât şi unde s-a rupt calculul.
- Cu
?anaf=1se adaugă un cross-check la validatorul ANAF, iar confirmarea lui apare separat înanaf_confirmation. Fără el, validarea e integral locală — acelaşi Schematron oficial, dar fără ca XML-ul să iasă din proces. - Cu
?vies=1se verifică suplimentar, în VIES (Comisia Europeană), codul de TVA al cumpărătorului non-RO — util la livrările intracomunitare scutite (categoriaK), unde scutirea e legală doar dacă partenerul are cod de TVA valid în alt stat membru. Schematron-ul verifică formatul; VIES confirmă că respectivul cod chiar există şi e activ. Rezultatul apare separat înviesşi nu afecteazăvalid. E un apel extern, opţional: dacă VIES nu răspunde, câmpul întoarcestate: unavailableşi validarea locală merge mai departe. - Un XML invalid nu e o eroare a cererii. Răspunsul e
200cuvalid: falseşi lista de erori înerrors[], fiecare cucod,mesajşicamp. „Invalid" fără să spui ce anume n-ajută pe cineva care încearcă să corecteze factura. codşi regula citată înmesajpot să nu coincidă — de pildăcod: BR-RO-081cu un mesaj care începe cu[BR-RO-080]. Nu e o eroare a noastră: schema oficialăROeFactura-UBL-validation-Invoice.xsltare aserţiuni distincte (adresa vânzătorului BT-35, adresa cumpărătorului BT-50) cu id-uri diferite, dar cu acelaşi prefix în text. Transmitem fidel ambele. Iacodca identificator al regulii, nu prefixul din text.- Zero retenţie: XML-ul primit nu se scrie şi nu se loghează; validarea e stateless.
La ce folosește
- Verificarea unei facturi generate în altă parte, înainte de depunere în SPV.
- Depanarea unui total care nu se leagă, folosind diferenţa exactă din stratul numeric.
- Cross-check la ANAF (
?anaf=1) pentru confirmare oficială, când verificarea locală nu e de ajuns. - Confirmarea în VIES (
?vies=1) a codului de TVA al cumpărătorului la o livrare intracomunitară scutită (categoriaK).
Structura răspunsului
CâmpTipDescriere
data.valid
boolean
Verdictul cumulat al celor trei straturi.
data.standard
string
Standardul detectat din XML:
FACT1 sau FCN.
data.schema_version
string
Schema/standardul folosit la validare, când e disponibil (ex.
FACT1 sau d390_v3.xsd); altfel null.
data.errors
array
Erorile de validare, fiecare
{cod,mesaj,camp}. Gol când valid e true.
data.warnings
array
Avertismente neblocante, în acelaşi format.
meta.generat_la
string
Momentul la care s-a construit răspunsul (ISO 8601).
data.anaf_confirmation
Rezultatul cross-check-ului ANAF
{state,reason,messages,trace_id}; apare doar la ?anaf=1. state: ok/nok (verdictul ANAF) ori unavailable când validatorul n-a dat un verdict — atunci reason spune de ce: timeout, connection, http_<cod>, unintelligible_response (de obicei pagina de mentenanţă, servită cu HTTP 200), circuit_open, throttled_user, throttled_global. unavailable nu înseamnă nok.
data.vies
Rezultatul verificării VIES
{state,reason,country,number,name}; apare doar la ?vies=1, pentru un cumpărător non-RO. state: valid/invalid/unavailable. La unavailable, reason spune de ce n-a existat verdict: member_state_unavailable, busy, timeout, connection, http_<cod>, unintelligible_response, circuit_open, throttled_user, throttled_global. unavailable nu înseamnă invalid.
Exemple de răspuns
body: @efactura.xml
POSThttps://oneapi.ro/api/anaf/v1/efactura/validate
{
"data": {
"valid": true,
"standard": "FACT1",
"schema_version": "CIUS-RO 1.0.1 (EN16931)",
"errors": [],
"warnings": []
},
"meta": {
"generat_la": "2026-10-06T23: 59: 42+03: 00"
}
}
body: @efactura-cii.xml
POSThttps://oneapi.ro/api/anaf/v1/efactura/validate
{
"data": {
"valid": true,
"standard": "FACT1",
"schema_version": "CIUS-RO 1.0.1 (EN16931)",
"errors": [],
"warnings": []
},
"meta": {
"generat_la": "2026-10-06T23: 59: 42+03: 00"
}
}
body: @efactura-corectata.xml
POSThttps://oneapi.ro/api/anaf/v1/efactura/validate
{
"data": {
"valid": true,
"standard": "FACT1",
"schema_version": "CIUS-RO 1.0.1 (EN16931)",
"errors": [],
"warnings": []
},
"meta": {
"generat_la": "2026-10-06T23: 59: 42+03: 00"
}
}
Coduri de eroare
| Cod | Slug | Când apare |
|---|---|---|
| 401 | neautentificat | Token lipsă, invalid, expirat sau revocat. |
| 403 | feature_indisponibil | Planul curent nu include funcţia de care ţine ruta. |
| 422 | xml_invalid | Corpul nu e XML parsabil. Un XML valid-ca-structură dar neconform întoarce 200 cu valid: false. |
| 429 | cota_depasita | Cota lunară a planului a fost depăşită (vezi Retry-After). |
Erorile modulului Anaf au acelaşi plic ca restul platformei, cu două câmpuri în plus: {eroare: {cod, mesaj, camp, request_id}}. eroare.cod e stabil şi e cel după care ramifici în cod; la validare (422) codul e specific cazului: xml_invalid, xml_nu_e_factura, unitate_necunoscuta, luna_invalida ş.a. camp arată câmpul vinovat, când se poate identifica.
{
"eroare": {
"cod": "xml_invalid",
"mesaj": "Corpul nu e XML parsabil. Un XML valid-ca-structură dar neconform întoarce 200 cu valid: false.",
"camp": "anaf",
"request_id": "0199c1f0-6e1a-7c3d-9b2f-4a8e5d1c7b04"
}
}