oneapi
Autentificare
Anaf v1 / e-Factura

Construieşte factura

Trimiţi factura în JSON şi primeşti XML-ul CIUS-RO (UBL 2.1), trecut prin XSD şi prin regulile Schematron înainte de a-ţi fi dat. Cu validate=anaf se poate cere şi verdictul validatorului ANAF.

POST
https://oneapi.ro/api/anaf/v1/efactura/build

Corpul cererii

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

Factură cu două linii Corpul cererii
{
    "number": "FCT-2026-0142",
    "issue_date": "2026-09-10",
    "due_date": "2026-10-10",
    "currency": "RON",
    "supplier": {
        "name": "Exemplu Furnizor SRL",
        "vat_id": "RO990000005",
        "address": {
            "country": "RO",
            "city": "Cluj-Napoca",
            "street": "Str. Memorandumului 28",
            "county": "RO-CJ"
        }
    },
    "customer": {
        "name": "Exemplu Client SRL",
        "vat_id": "RO990000072",
        "address": {
            "country": "RO",
            "city": "SECTOR1",
            "street": "Calea Victoriei 1",
            "county": "RO-B"
        }
    },
    "lines": [
        {
            "name": "Servicii de consultanţă",
            "quantity": 2,
            "unit": "H87",
            "unit_price": 100,
            "vat": {
                "rate": 21
            }
        },
        {
            "name": "Licenţă software anuală",
            "quantity": 1,
            "unit": "H87",
            "unit_price": 500,
            "vat": {
                "rate": 21
            }
        }
    ]
}
Notă de credit (stornare) Corpul cererii
{
    "type": "credit_note",
    "number": "STN-2026-0007",
    "issue_date": "2026-09-20",
    "currency": "RON",
    "supplier": {
        "name": "Exemplu Furnizor SRL",
        "vat_id": "RO990000005",
        "address": {
            "country": "RO",
            "city": "Cluj-Napoca",
            "street": "Str. Memorandumului 28",
            "county": "RO-CJ"
        }
    },
    "customer": {
        "name": "Exemplu Client SRL",
        "vat_id": "RO990000072",
        "address": {
            "country": "RO",
            "city": "SECTOR1",
            "street": "Calea Victoriei 1",
            "county": "RO-B"
        }
    },
    "lines": [
        {
            "name": "Stornare servicii de consultanţă",
            "quantity": 1,
            "unit": "H87",
            "unit_price": 200,
            "vat": {
                "rate": 21
            }
        }
    ],
    "preceding_invoices": [
        {
            "number": "FCT-2026-0142",
            "issue_date": "2026-09-10"
        }
    ]
}
Livrare intracomunitară, în euro Corpul cererii
{
    "number": "FCT-2026-0150",
    "issue_date": "2026-09-25",
    "due_date": "2026-10-25",
    "currency": "EUR",
    "exchange_rate": 5.0821,
    "supplier": {
        "name": "Exemplu Furnizor SRL",
        "vat_id": "RO990000005",
        "address": {
            "country": "RO",
            "city": "Cluj-Napoca",
            "street": "Str. Memorandumului 28",
            "county": "RO-CJ"
        }
    },
    "customer": {
        "name": "Exemplu Client GmbH",
        "vat_id": "DE999000009",
        "address": {
            "country": "DE",
            "city": "Muenchen",
            "street": "Leopoldstrasse 1",
            "county": "DE-BY"
        }
    },
    "delivery": {
        "date": "2026-09-24",
        "address": {
            "country": "DE",
            "city": "Muenchen",
            "street": "Leopoldstrasse 1",
            "county": "DE-BY"
        }
    },
    "lines": [
        {
            "name": "Licenţă software anuală",
            "quantity": 1,
            "unit": "H87",
            "unit_price": 1200,
            "vat": {
                "rate": 0,
                "category": "K"
            }
        }
    ]
}

Parametri de interogare

NumeTipDescriereValori acceptate
validateopțional string Stratul de validare: local (implicit, Schematron oficial rulat local), anaf (local + cross-check la validatorul ANAF), none (doar generare, fără validare). ex. localex. anafex. none
strictopțional boolean true (implicit) întoarce 422 fără XML dacă validarea eşuează; false întoarce XML-ul oricum, cu valid: false şi erorile. ex. false
formatopțional text Forma XML-ului în răspuns: xml (implicit, text) sau base64. ex. base64

Cum se comportă

  • Primeşte un JSON de business — vânzător, cumpărător, linii, cote — şi întoarce XML-ul CIUS-RO (UBL 2.1) al facturii, gata de depus la ANAF. Este inversul lui /anaf/v1/efactura/parse: acolo citeşti o factură primită, aici o construieşti pe a ta.
  • Categoria de TVA se derivă automat din context — cota, ţara clientului, prezenţa şi tipul codului de TVA — nu se declară manual. Motorul acoperă întreg spectrul fiscal: cotă standard, facturi multi-cotă, taxare inversă (AE), livrare intracomunitară (K), export (G), servicii către UE (O), neplătitor de TVA, B2C cu cod fiscal completat cu 13 de zero, notă de credit, factură rectificativă, avans, valută străină, TVA la încasare şi autofacturare.
  • validate alege stratul de validare. La local (implicit) se rulează Schematron-ul oficial (EN 16931 + CIUS-RO + RO-eFactura) local, prin Saxon — acelaşi set de reguli pe care îl aplică ANAF, fără să iasă payload-ul din proces. La anaf se adaugă un cross-check la validatorul ANAF; la none doar se generează XML-ul, fără validare.
  • strict decide ce se întâmplă când validarea eşuează. La true (implicit) răspunsul e 422 şi nu primeşti XML — factura nu e depozabilă, deci nu are rost s-o trimiţi. La false primeşti XML-ul oricum, cu valid: false şi lista de erori, ca să-l poţi inspecta şi corecta.
  • Zero retenţie. Payload-ul nu se scrie pe disc, nu se loghează, nu intră în chei de cache. Ruta e POST şi necachabilă tocmai pentru că o factură conţine date comerciale şi personale care n-au ce căuta în loguri de acces sau în telemetrie.
  • Erorile de structură (câmp lipsă, cotă imposibilă, sumă care nu se leagă) vin ca 422 în formatul comun {eroare:{cod,mesaj,camp}}, unde camp arată exact unde e problema în JSON-ul trimis.
  • Câmpurile corpului sunt în engleză, singura excepţie din platformă (restul rutelor folosesc nume româneşti). Motivul: intrarea oglindeşte modelul semantic EN 16931 / UBL (supplier, issue_date, unit_price, vat_id), aşa că un câmp din JSON se citeşte direct în specificaţie, fără un dicţionar intermediar. Mesajele de eroare rămân în română.
  • Un câmp necunoscut în corp e respins, nu ignorat. unit_code în loc de unit, seller în loc de supplier — primeşti 422 camp_necunoscut cu lista celor acceptate la acel nivel. Altfel ai fi primit o factură validă construită pe valorile implicite, fără să afli că a ta n-a fost citită.

La ce folosește

  • Generarea XML-ului CIUS-RO dintr-un model intern de factură, înainte de depunere în SPV.
  • Producerea unei note de credit sau a unei facturi rectificative din datele deja existente.
  • Verificarea, la validate=local, că o factură trece Schematron-ul oficial fără s-o trimiţi încă la ANAF.

Structura răspunsului

CâmpTipDescriere
data.valid boolean Rezultatul validării; null la validate=none.
data.standard string Standardul detectat: FACT1 (factură) sau FCN (notă de credit).
data.xml string XML-ul CIUS-RO generat; text sau base64 după format.
data.meta.customization_id string Identificatorul CIUS-RO al specificaţiei aplicate.
data.meta.document_type_code string Codul tipului de document (ex. 380 factură, 381 notă de credit).
data.meta.totals object Totalurile calculate: bază, TVA, total de plată.
data.meta.totals.lines_net integer
data.meta.totals.allowance_total integer
data.meta.totals.charge_total integer
data.meta.totals.taxable_base integer
data.meta.totals.vat integer
data.meta.totals.gross integer
data.meta.totals.prepaid integer
data.meta.totals.rounding integer
data.meta.totals.payable integer
data.meta.vat_breakdown[] array Defalcarea pe categorii de TVA, cu baza şi cota fiecăreia.
data.meta.vat_breakdown[].category string
data.meta.vat_breakdown[].rate integer
data.meta.vat_breakdown[].base integer
data.meta.vat_breakdown[].amount integer
data.errors array Erorile de validare, când strict=false (la strict=true vin în plicul de eroare).
data.warnings array Avertismente neblocante, în formatul {cod,mesaj,camp}.
meta.generat_la string Momentul la care s-a construit răspunsul (ISO 8601).

Exemple de răspuns

body: {"number": "FCT-2026-0142", "issue_date": "2026-09-10", "due_date": "2026-10-10", "currency": "RON", "supplier": {"name": "Exemplu Furnizor SRL", "vat_id": "RO990000005", "address": {"country": "RO", "city": "Cluj-Napoca", "street": "Str. Memorandumului 28", "county": "RO-CJ"}}, "customer": {"name": "Exemplu Client SRL", "vat_id": "RO990000072", "address": {"country": "RO", "city": "SECTOR1", "street": "Calea Victoriei 1", "county": "RO-B"}}, "lines": [{"name": "Servicii de consultanţă", "quantity": 2, "unit": "H87", "unit_price": 100, "vat": {"rate": 21}}, {"name": "Licenţă software anuală", "quantity": 1, "unit": "H87", "unit_price": 500, "vat": {"rate": 21}}]}

POSThttps://oneapi.ro/api/anaf/v1/efactura/build
{
    "data": {
        "valid": true,
        "standard": "FACT1",
        "xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\" xmlns:cac=\"urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2\" xmlns:cbc=\"urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2\">\n  <cbc:CustomizationID>urn:cen.eu:en16931: 2017#compliant#urn:efactura.mfinante.ro:CIUS-RO: 1.0.1</cbc:CustomizationID>\n  <cbc:ID>FCT-2026-0142</cbc:ID>\n  <cbc:IssueDate>2026-09-10</cbc:IssueDate>\n  <cbc:DueDate>2026-10-10</cbc:DueDate>\n  <cbc:InvoiceTypeCode>380</cbc:InvoiceTypeCode>\n  <cbc:DocumentCurrencyCode>RON</cbc:DocumentCurrencyCode>\n  <cac:AccountingSupplierParty>\n    <cac:Party>\n      <cac:PostalAddress>\n        <cbc:StreetName>Str. Memorandumului 28</cbc:StreetName>\n        <cbc:CityName>Cluj-Napoca</cbc:CityName>\n        <cbc:CountrySubentity>RO-CJ</cbc:CountrySubentity>\n        <cac:Country>\n          <cbc:IdentificationCode>RO</cbc:IdentificationCode>\n        </cac:Country>\n      </cac:PostalAddress>\n      <cac:PartyTaxScheme>\n        <cbc:CompanyID>RO990000005</cbc:CompanyID>\n        <cac:TaxScheme>\n          <cbc:ID>VAT</cbc:ID>\n        </cac:TaxScheme>\n      </cac:PartyTaxScheme>\n      <cac:PartyLegalEntity>\n        <cbc:RegistrationName>Exemplu Furnizor SRL</cbc:RegistrationName>\n      </cac:PartyLegalEntity>\n    </cac:Party>\n  </cac:AccountingSupplierParty>\n  <cac:AccountingCustomerParty>\n    <cac:Party>\n      <cac:PostalAddress>\n        <cbc:StreetName>Calea Victoriei 1</cbc:StreetName>\n        <cbc:CityName>SECTOR1</cbc:CityName>\n        <cbc:CountrySubentity>RO-B</cbc:CountrySubentity>\n        <cac:Country>\n          <cbc:IdentificationCode>RO</cbc:IdentificationCode>\n        </cac:Country>\n      </cac:PostalAddress>\n      <cac:PartyTaxScheme>\n        <cbc:CompanyID>RO990000072</cbc:CompanyID>\n        <cac:TaxScheme>\n          <cbc:ID>VAT</cbc:ID>\n        </cac:TaxScheme>\n      </cac:PartyTaxScheme>\n      <cac:PartyLegalEntity>\n        <cbc:RegistrationName>Exemplu Client SRL</cbc:RegistrationName>\n      </cac:PartyLegalEntity>\n    </cac:Party>\n  </cac:AccountingCustomerParty>\n  <cac:TaxTotal>\n    <cbc:TaxAmount currencyID=\"RON\">147.00</cbc:TaxAmount>\n    <cac:TaxSubtotal>\n      <cbc:TaxableAmount currencyID=\"RON\">700.00</cbc:TaxableAmount>\n      <cbc:TaxAmount currencyID=\"RON\">147.00</cbc:TaxAmount>\n      <cac:TaxCategory>\n        <cbc:ID>S</cbc:ID>\n        <cbc:Percent>21</cbc:Percent>\n        <cac:TaxScheme>\n          <cbc:ID>VAT</cbc:ID>\n        </cac:TaxScheme>\n      </cac:TaxCategory>\n    </cac:TaxSubtotal>\n  </cac:TaxTotal>\n  <cac:LegalMonetaryTotal>\n    <cbc:LineExtensionAmount currencyID=\"RON\">700.00</cbc:LineExtensionAmount>\n    <cbc:TaxExclusiveAmount currencyID=\"RON\">700.00</cbc:TaxExclusiveAmount>\n    <cbc:TaxInclusiveAmount currencyID=\"RON\">847.00</cbc:TaxInclusiveAmount>\n    <cbc:PayableAmount currencyID=\"RON\">847.00</cbc:PayableAmount>\n  </cac:LegalMonetaryTotal>\n  <cac:InvoiceLine>\n    <cbc:ID>1</cbc:ID>\n    <cbc:InvoicedQuantity unitCode=\"H87\">2</cbc:InvoicedQuantity>\n    <cbc:LineExtensionAmount currencyID=\"RON\">200.00</cbc:LineExtensionAmount>\n    <cac:Item>\n      <cbc:Name>Servicii de consultanţă</cbc:Name>\n      <cac:ClassifiedTaxCategory>\n        <cbc:ID>S</cbc:ID>\n        <cbc:Percent>21</cbc:Percent>\n        <cac:TaxScheme>\n          <cbc:ID>VAT</cbc:ID>\n        </cac:TaxScheme>\n      </cac:ClassifiedTaxCategory>\n    </cac:Item>\n    <cac:Price>\n      <cbc:PriceAmount currencyID=\"RON\">100.00</cbc:PriceAmount>\n    </cac:Price>\n  </cac:InvoiceLine>\n  <cac:InvoiceLine>\n    <cbc:ID>2</cbc:ID>\n    <cbc:InvoicedQuantity unitCode=\"H87\">1</cbc:InvoicedQuantity>\n    <cbc:LineExtensionAmount currencyID=\"RON\">500.00</cbc:LineExtensionAmount>\n    <cac:Item>\n      <cbc:Name>Licenţă software anuală</cbc:Name>\n      <cac:ClassifiedTaxCategory>\n        <cbc:ID>S</cbc:ID>\n        <cbc:Percent>21</cbc:Percent>\n        <cac:TaxScheme>\n          <cbc:ID>VAT</cbc:ID>\n        </cac:TaxScheme>\n      </cac:ClassifiedTaxCategory>\n    </cac:Item>\n    <cac:Price>\n      <cbc:PriceAmount currencyID=\"RON\">500.00</cbc:PriceAmount>\n    </cac:Price>\n  </cac:InvoiceLine>\n</Invoice>\n",
        "meta": {
            "customization_id": "urn:cen.eu:en16931: 2017#compliant#urn:efactura.mfinante.ro:CIUS-RO: 1.0.1",
            "document_type_code": "380",
            "totals": {
                "lines_net": 700,
                "allowance_total": 0,
                "charge_total": 0,
                "taxable_base": 700,
                "vat": 147,
                "gross": 847,
                "prepaid": 0,
                "rounding": 0,
                "payable": 847
            },
            "vat_breakdown": [
                {
                    "category": "S",
                    "rate": 21,
                    "base": 700,
                    "amount": 147
                }
            ]
        },
        "errors": [],
        "warnings": []
    },
    "meta": {
        "generat_la": "2026-10-06T23: 59: 42+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.
422xml_invalidJSON de business invalid (câmp lipsă/greşit) sau — la strict=true — factură care nu trece validarea. Corpul poartă error plus errors[]/warnings[].
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": "JSON de business invalid (câmp lipsă/greşit) sau — la strict=true — factură care nu trece validarea. Corpul poartă error plus errors[]/warnings[].",
        "camp": "validate",
        "request_id": "0199c1f0-6e1a-7c3d-9b2f-4a8e5d1c7b04"
    }
}