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.
Request body
Sent as JSON in the request body (Content-Type: application/json) — not in the query string.
{id, xml} — with id, results come labelled with your identifier rather than the list position.
{
"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.
{
"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.
Query parameters
How it behaves
- An element of
documentecan be the XML itself (text or base64) or the object{id, xml}— the same shapefacturiaccepts at/reconciliere-facturiand/declaratii/deriva. Withidyou 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}]}, wherexmlis 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
id) or the list index.
null if the document was not recognized).
true/false, or null when validation could not run.
{cod,mesaj,camp}.
{cod,mesaj,camp}.
total, valide, invalide, nerecunoscute.
Response examples
body: {"documente": ["@efactura.xml", "@etransport.xml", "@d394.xml"]}
{
"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"
}
}
body: {"documente": ["@efactura.xml", "@efactura-stornare.xml", "@efactura-intracomunitara.xml"]}
{
"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-d809-73d3-9354-bc92928f8e9c"
}
}
body: {"documente": ["@d100.xml", "@d390.xml", "@d311.xml", "@d394.xml"]}
{
"data": {
"rezultate": [
{
"id": 0,
"tip": "D100",
"produs": "declaratii",
"valid": true,
"nr_erori": 0,
"errors": [],
"warnings": []
}
],
"sumar": {
"total": 4,
"valide": 4,
"invalide": 0,
"nerecunoscute": 0
}
},
"meta": {
"generat_la": "2026-10-06T23: 59: 41+03: 00",
"request_id": "01a11303-d82a-711d-a0db-d7da897e29b4"
}
}
Error codes
| Code | Slug | When it occurs |
|---|---|---|
| 401 | neautentificat | Token missing, invalid, expired or revoked. |
| 403 | feature_indisponibil | The current plan does not include the feature the route depends on. |
| 422 | xml_invalid | Body without documente (or empty), or over 50 documents. |
| 429 | cota_depasita | The 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"
}
}