oneapi
Autentificare
Anaf v1 / Utilitare cross-zonă

Diferențele dintre două documente

Două documente de acelaşi tip, câmp cu câmp: ce s-a adăugat, ce s-a scos şi ce s-a schimbat. Pentru a vedea exact ce aduce o corecţie faţă de documentul iniţial.

POST
https://oneapi.ro/api/anaf/v1/diff

Corpul cererii

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

NumeTipDescriereValori acceptate
aobligatoriu string Primul document (versiunea de referinţă), XML brut ori base64.
bobligatoriu string Al doilea document, de acelaşi tip cu a, XML brut ori base64.
Factură şi corectura ei Corpul cererii
{
    "a": "@efactura.xml",
    "b": "@efactura-corectata.xml"
}

În exemplu, @efactura.xml, @efactura-corectata.xml ţin locul unor documente întregi: trimiţi conţinutul fişierului — XML-ul ca text sau base64, un PDF ca base64 — nu numele lui.

Factură față de stornarea ei Corpul cererii
{
    "a": "@efactura.xml",
    "b": "@efactura-stornare.xml"
}

În exemplu, @efactura.xml, @efactura-stornare.xml ţin locul unor documente întregi: trimiţi conţinutul fişierului — XML-ul ca text sau base64, un PDF ca base64 — nu numele lui.

Două notificări de transport Corpul cererii
{
    "a": "@etransport.xml",
    "b": "@etransport-lic.xml"
}

În exemplu, @etransport.xml, @etransport-lic.xml ţin locul unor documente întregi: trimiţi conţinutul fişierului — XML-ul ca text sau base64, un PDF ca base64 — nu numele lui.

D100 înainte și după rectificare Corpul cererii
{
    "a": "@d100.xml",
    "b": "@d100-rectificat.xml"
}

În exemplu, @d100.xml, @d100-rectificat.xml ţin locul unor documente întregi: trimiţi conţinutul fişierului — XML-ul ca text sau base64, un PDF ca base64 — nu numele lui.

Parametri de interogare

Ruta nu acceptă parametri de interogare.

Cum se comportă

  • Compară DOUĂ documente ANAF de același tip și întoarce ce s-a schimbat, câmp cu câmp — de regulă „varianta veche" vs „varianta nouă". Merge pe orice produs al platformei (e-Factura, e-Transport, SAF-T, declarații D): tipul se detectează singur din root/namespace.
  • Corp JSON: {a: "<xml>", b: "<xml>"} (XML brut sau base64). Comparația se face pe JSON-ul de business (rezultatul parserului), nu pe XML brut, așa că fiecare diferență vine cu o cale pe câmpuri cu nume (linii.0.pret), nu cu un nod XML.
  • Listele se compară pozițional, pe index: o linie inserată la mijloc apare ca un lanț de modificări plus una adăugată la coadă. Nu ghicim identitatea elementelor dintr-o listă.
  • Nu interpretează nimic fiscal — raportează strict ce diferă. Peste 500 de diferențe răspunsul e trunchiat (trunchiat: true).
  • Zero retenție și fără SPV — totul e in-memory.

La ce folosește

  • Vezi exact ce s-a schimbat între factura inițială și cea corectată, înainte să trimiți storno-ul sau varianta nouă.
  • Verifici, înainte de depunere, ce diferă între declarația depusă luna trecută și varianta pe care o pregătești acum.
  • Audit intern: dovedești ce câmpuri s-au modificat între două versiuni ale aceluiași document.

Structura răspunsului

CâmpTipDescriere
data.tip string Tipul detectat al documentelor (identic pentru ambele, altfel eroare).
data.produs string Produsul căruia îi aparține tipul (efactura, etransport, saft, declaratii).
data.identice boolean true dacă nu există nicio diferență.
data.sumar object Numărători: modificate, adaugate, sterse, total.
data.sumar.modificate integer
data.sumar.adaugate integer
data.sumar.sterse integer
data.sumar.total integer
data.modificate[] array Câmpuri prezente în ambele, cu valori diferite [{cale,inainte,dupa}].
data.modificate[].cale string Calea în ierarhie, de la rădăcină până la elementul curent.
data.modificate[].inainte integer
data.modificate[].dupa integer
data.adaugate array Câmpuri prezente doar în b [{cale,valoare}].
data.sterse array Câmpuri prezente doar în a [{cale,valoare}].
data.trunchiat boolean true dacă s-au depășit 500 de diferențe și listele au fost tăiate.
meta.generat_la string Momentul la care s-a construit răspunsul (ISO 8601).
meta.request_id string Identificatorul cererii. Dă-l când raportezi o problemă: după el se găseşte răspunsul.

Exemple de răspuns

body: {"a": "@efactura.xml", "b": "@efactura-corectata.xml"}

POSThttps://oneapi.ro/api/anaf/v1/diff
{
    "data": {
        "tip": "e-Factura",
        "produs": "efactura",
        "identice": false,
        "sumar": {
            "modificate": 1,
            "adaugate": 0,
            "sterse": 0,
            "total": 1
        },
        "modificate": [
            {
                "cale": "lines.0.quantity",
                "inainte": 2,
                "dupa": 3
            }
        ],
        "adaugate": [],
        "sterse": [],
        "trunchiat": false
    },
    "meta": {
        "generat_la": "2026-10-06T23: 59: 41+03: 00",
        "request_id": "01a11303-d891-7144-ae4c-bffcf733ff72"
    }
}

Coduri de eroare

CodSlugCând apare
401neautentificatToken lipsă, invalid, expirat sau revocat.
403feature_indisponibilPlanul curent nu include funcţia de care ţine ruta.
422xml_invalidLipsește a sau b; un document nu e XML valid ori nu e recunoscut; cele două documente sunt de tipuri diferite.
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": "xml_invalid",
        "mesaj": "Lipsește a sau b; un document nu e XML valid ori nu e recunoscut; cele două documente sunt de tipuri diferite.",
        "camp": null,
        "request_id": "0199c1f0-6e1a-7c3d-9b2f-4a8e5d1c7b04"
    }
}