oneapi
Autentificare
Anaf v1 / SAF-T (D406)

Validează D406

Verdictul XSD-ului oficial SAF-T pe un D406, plus verificările proprii care prind lucrurile pe care schema le lasă să treacă — perioade incoerente şi totaluri care nu se închid.

POST
https://oneapi.ro/api/anaf/v1/saft/validate

Corpul cererii

Corpul cererii e documentul întreg, trimis brut (Content-Type: application/xml) — nu un obiect cu câmpuri.

Declarație D406

saft-d406.xml application/xml · 17,5 KB — se trimite ca atare, în corpul cererii.

D406 trimestrial

saft-d406-trimestrial.xml application/xml · 17,5 KB — se trimite ca atare, în corpul cererii.

D406 anual

saft-d406-anual.xml application/xml · 17,5 KB — se trimite ca atare, în corpul cererii.

Parametri de interogare

Ruta nu acceptă parametri de interogare.

Cum se comportă

  • Documentul se poate trimite şi ca fişier: multipart/form-data cu câmpul fisier (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ă fisier dă 422 camp_necunoscut.
  • Primește fișierul standard de control fiscal (D406/SAF-T) în corpul cererii și întoarce verdictul de validare: (1) structural — XSD-ul oficial ANAF (v2.4.9), validat nativ; (2) verificări proprii — root <AuditFile>, prezența <Header> și echilibrul jurnalului (Σ debit = Σ credit).
  • SAF-T nu are un Schematron public — regulile de business oficiale sunt în validatorul ANAF (DUKIntegrator, jar), pe care nu-l reimplementăm; XSD-ul + verificările proprii prind grosul erorilor de structură și de calcul înainte de depunere.
  • Un XML invalid nu e o eroare a cererii: răspunsul e 200 cu valid:false și lista erorilor în errors[], fiecare cu cod, mesaj, camp.
  • Zero retenție: fișierul primit nu se scrie și nu se loghează.

La ce folosește

  • Verificarea unui D406 generat de softul de contabilitate, înainte de depunerea în SPV.
  • Prinderea unui jurnal dezechilibrat (debit ≠ credit) înainte ca ANAF să respingă fișierul.

Structura răspunsului

CâmpTipDescriere
data.valid boolean Verdictul cumulat (XSD + verificări proprii).
data.standard string D406.
data.schema_version string Schema/standardul folosit la validare, când e disponibil (ex. FACT1 sau d390_v3.xsd); altfel null.
data.xsd_checked boolean Dacă validarea XSD a rulat.
data.errors array Erorile de validare {cod,mesaj,camp}. Gol când valid e true.
data.warnings array Avertismente neblocante (ex. jurnal dezechilibrat).
meta.generat_la string Momentul la care s-a construit răspunsul (ISO 8601).

Exemple de răspuns

body: @saft-d406.xml

POSThttps://oneapi.ro/api/anaf/v1/saft/validate
{
    "data": {
        "valid": true,
        "standard": "D406",
        "schema_version": "RO SAF-T v2.4.9 (2025)",
        "xsd_checked": true,
        "errors": [],
        "warnings": []
    },
    "meta": {
        "generat_la": "2026-10-06T23: 59: 44+03: 00"
    }
}

Coduri de eroare

CodSlugCând apare
401neautentificatToken lipsă, invalid, expirat sau revocat.
403feature_indisponibilPlanul curent nu include funcţia de care ţine ruta.
413payload_prea_mareDocumentul depăşeşte limita acceptată.
422parametru_necunoscutUn parametru în query pe care ruta nu-l primeşte.
429cota_depasitaCota 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": "parametru_necunoscut",
        "mesaj": "Un parametru în query pe care ruta nu-l primeşte.",
        "camp": null,
        "request_id": "0199c1f0-6e1a-7c3d-9b2f-4a8e5d1c7b04"
    }
}