oneapi
Sign in
Anaf v1 / Utilitare cross-zonă

Validate in batch

Validates several documents at once, of different types — invoices, returns and transport notifications in the same batch. Each gets its own verdict, and a summary at the end says how many passed.

POST
https://oneapi.ro/api/anaf/v1/valideaza-lot

Request body

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

NameTypeDescriptionAccepted values
documenterequired string[] | object[] The documents to validate, at most 50. An item is either the XML itself (text or base64) or the object {id, xml} — with id, results come labelled with your identifier rather than the list position.
Three different documents Request body
{
    "documente": [
        "@efactura.xml",
        "@etransport.xml",
        "@d394.xml"
    ]
}

In this example, @efactura.xml, @etransport.xml, @d394.xml stand in for whole documents: send the file content — XML as text or base64, a PDF as base64 — not its name.

Three invoices from one month Request body
{
    "documente": [
        "@efactura.xml",
        "@efactura-stornare.xml",
        "@efactura-intracomunitara.xml"
    ]
}

In this example, @efactura.xml, @efactura-stornare.xml, @efactura-intracomunitara.xml stand in for whole documents: send the file content — XML as text or base64, a PDF as base64 — not its name.

Four different returns Request body
{
    "documente": [
        "@d100.xml",
        "@d390.xml",
        "@d311.xml",
        "@d394.xml"
    ]
}

In this example, @d100.xml, @d390.xml, @d311.xml, @d394.xml stand in for whole documents: send the file content — XML as text or base64, a PDF as base64 — not its name.

Query parameters

This route accepts no query parameters.

How it behaves

  • An element of documente can be the XML itself (text or base64) or the object {id, xml} — the same shape facturi accepts at /reconciliere-facturi and /declaratii/deriva. With id you get the results labelled with your own identifier instead of the list position.
  • Validates several (heterogeneous) ANAF documents in a single call. The body is JSON: {documente:[{id?, xml}]}, where xml is raw or base64. Each document is auto-detected and routed to its product validator (e-Invoice, e-Transport, SAF-T, "D" declarations).
  • A broken document does not break the batch: errors are isolated per item and reported, the rest validate normally.
  • A cap of 50 documents per call (Schematron/XSD validation is expensive per document).
  • Zero retention: the documents received are not written and not logged.

What it is for

  • Validating a set of invoices/declarations exported from an ERP, in one request.
  • Bulk pre-checking files before filing them in SPV.

Response structure

FieldTypeDescription
data.rezultate[] array One verdict per document, in the order submitted.
data.rezultate[].id integer The client-provided identifier (id) or the list index.
data.rezultate[].tip string The detected type (or null if the document was not recognized).
data.rezultate[].produs string Product from the source code list.
data.rezultate[].valid boolean The verdict: true/false, or null when validation could not run.
data.rezultate[].nr_erori integer The number of errors for the document.
data.rezultate[].errors array The errors {cod,mesaj,camp}.
data.rezultate[].warnings array The non-blocking warnings {cod,mesaj,camp}.
data.sumar object Batch aggregate: total, valide, invalide, nerecunoscute.
data.sumar.total integer
data.sumar.valide integer
data.sumar.invalide integer
data.sumar.nerecunoscute integer
meta.generat_la string When the response was built (ISO 8601).
meta.request_id string The identifier of this request. Quote it when reporting a problem — it is what the answer is found by.

Response examples

body: {"documente": ["@efactura.xml", "@etransport.xml", "@d394.xml"]}

POSThttps://oneapi.ro/api/anaf/v1/valideaza-lot
{
    "data": {
        "rezultate": [
            {
                "id": 0,
                "tip": "e-Factura",
                "produs": "efactura",
                "valid": true,
                "nr_erori": 0,
                "errors": [],
                "warnings": []
            }
        ],
        "sumar": {
            "total": 3,
            "valide": 3,
            "invalide": 0,
            "nerecunoscute": 0
        }
    },
    "meta": {
        "generat_la": "2026-10-06T23: 59: 41+03: 00",
        "request_id": "01a11303-d7d3-727f-b28c-1623f1a1fd48"
    }
}

Error codes

CodeSlugWhen it occurs
401neautentificatToken missing, invalid, expired or revoked.
403feature_indisponibilThe current plan does not include the feature the route depends on.
422xml_invalidBody without documente (or empty), or over 50 documents.
429cota_depasitaThe plan's monthly quota has been exceeded (see Retry-After).

Errors in the Anaf module use the same envelope as the rest of the platform, with two extra fields: {eroare: {cod, mesaj, camp, request_id}}. eroare.cod is stable and is what you branch on; on validation (422) the code is case-specific: xml_invalid, xml_nu_e_factura, unitate_necunoscuta, luna_invalida and so on. camp points at the offending field when one can be identified.

{
    "eroare": {
        "cod": "xml_invalid",
        "mesaj": "Body without documente (or empty), or over 50 documents.",
        "camp": null,
        "request_id": "0199c1f0-6e1a-7c3d-9b2f-4a8e5d1c7b04"
    }
}