You declare goods transport, in one call.
Turn a business JSON into a valid e-Transport declaration XML (schema v2), validate it with the official ANAF XSD and Schematron and render it as a PDF — all through one API, without storing anything.
This is not a dataset, it is a tool. You send the transport as an object and get back the XML, the validation verdict and, on request, a summary PDF. Processing happens in memory; the content never touches a disk of ours.
{
"declarant": { "cui": "RO12345678" }, // your business object
"operatiune": "30", // TTN — domestic transport
"bunuri": [ { "cod_tarifar": "0409", "cantitate": 500 } ]
}
// → { valid: true, xml: "<eTransport…", meta: { … } }
- Standard
- e-Transport declaration v2
- Namespace
- mfp:anaf:dgti:eTransport
- Operations
- build · validate · parse · render
- Code lists
- operations, CN, border points, customs offices
- Retention
- none
e-Transport compliance is hard. And it is not your product.
Between your business object and an XML that ANAF accepts when you declare a transport sits a layer of rules that keeps changing and that someone has to keep current.
Declaration v2
The declaration is not a JSON, it is an XML in the namespace mfp:anaf:dgti:eTransport:declaratie:v2, with dozens of ordered elements and strict cardinalities. One missing field, one wrong order, and the file is rejected.
Code lists
Operation types (domestic transport, intra-community acquisition or supply, import, export), CN tariff codes for goods, units of measure, border crossing points and customs offices. Official lists with permitted values.
Dozens of transport scenarios
Domestic transport, intra-community acquisition and supply, import and export, transit, transfer between warehouses. Each has its own rules about which departure and arrival places appear — an internal location or a border point — and which fields are mandatory.
Schematron
Real validation is not only against the XSD schema but also against the ANAF business rules, written in Schematron. Dozens of assertions about the coherence of the data — goods, partner, transport, locations — that have to be run correctly.
Locations and the border
A departure or arrival place is either an internal location (county, locality, street) or a border crossing point with a customs office. The rules about which variant is allowed depend on the operation type.
Rules that change
The specification gets revised, the code lists grow, the assertions get adjusted. What was valid last year can be rejected today, and you find out from the rejection, not from an announcement.
Four operations and a code list.
Each is an independent POST call. You use the one you need; nothing forces you through all of them.
/build
Build
You send the transport as business JSON and get a valid v2 declaration XML back. Element order, the namespace, the goods, the partner, the transport and the locations are set correctly by us, from your object.
/validate
Validate
You run an existing XML through the official XSD and Schematron locally. You get the verdict, what was checked (XSD and Schematron), the list of errors and the list of warnings.
/parse
Parse
A declaration XML you received becomes clean JSON, with the fields unpacked — declarant, operation, goods, partner, transport, locations, documents — so you can read it without touching the XML.
/render
Render
From the declaration or the XML comes a human-readable summary PDF, generated locally. The view for the driver or for the transport file, without an external rendering service.
/codes
Code lists
The official lists the declaration accepts — operation types, CN tariff codes, units of measure, border crossing points, customs offices — served as a reference, so you can validate from the form.
Your transports go nowhere. Not to us, not to ANAF.
This is the answer to “why would I send my transport data to a third party”. Because, in practice, you are not sending it anywhere — we process and forget.
Processed in memory
The payload is never written to disk. It arrives in the request, is transformed in memory and is gone when the response leaves. There is no file of your declaration at our end.
Local validation
The official XSD and Schematron run on our side, on the server holding your response. We do not send the declaration to ANAF to find out whether it is valid — the rules are here, the verdict is local.
Logs without content
What we keep is a result code and a duration — that is all. The VAT number, the goods, the vehicle registration, the partner go into no log, neither ours nor an observability service’s.
Not even the XML
An optional header tells us not to return the XML either, only the verdict. For integrations where you want the validation but would rather the document did not travel back whole.
We do not just say “invalid”. We say exactly what and where.
We run the official rules in full, locally — XSD plus Schematron — and give you the per-field diagnosis the ANAF validator does not give you before you file.
Official XSD schema
We first check the structure against the official v2 declaration XSD: elements, types, order, cardinalities. If a mandatory field is missing or a type does not match, we catch it before it ever reaches SPV.
Official Schematron
On top of the XSD we run the complete set of ANAF business rules, written in Schematron, executed locally. The coherence between operation, goods, partner, transport and locations is checked with the same assertions ANAF uses.
Diagnosis, not just a verdict
The response tells you what was checked — XSD and Schematron — whether the declaration is valid, plus the list of errors and warnings with the rule and the field involved. The difference between knowing there is a problem and knowing where it is.
No filing in SPV
Validation is entirely local: by default, nothing leaves us for ANAF. Obtaining the UIT code through SPV stays with you, using your own credentials — we give you the valid XML and the verdict before that step.
From domestic transport to an import through a customs office.
The real transport scenarios, not just the textbook example. Each with the correct operation type, locations and codes, already built.
We cover the full e-Transport v2 declaration, with internal locations and border points. If you hit a scenario we do not handle correctly, write to us — real cases take priority in what we build.
A transport object in. Valid XML out.
You send the transport as business JSON and get the verdict and the declaration XML. No mandatory SDK — the HTTP client you already have.
# build: a minimal transport object → valid e-Transport v2 XML
curl "https://oneapi.ro/api/anaf/v1/etransport/build" \
-H "Authorization: Bearer $ONEAPI_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"declarant": { "cui": "RO12345678" },
"operatiune": "30",
"bunuri": [
{ "scop": "101", "cod_tarifar": "0409", "denumire": "Miere",
"cantitate": 500, "unitate": "KGM", "greutate_bruta": 520, "valoare": 7500 }
],
"transport": { "nr_vehicul": "B123ABC", "data": "2026-09-01" },
"loc_start": { "locatie": { "judet": "CJ", "localitate": "Cluj-Napoca" } },
"loc_final": { "locatie": { "judet": "B", "localitate": "București" } }
}'
# → 200 OK
{
"valid": true,
"xml": "<eTransport xmlns=…>…</eTransport>",
"meta": { "operatiune": "30", "bunuri": 1, "greutate_bruta": 520 }
}
What was checked, the rule and the field
A validation response does not just say “invalid”. It tells you what was checked — XSD and Schematron — whether it is valid, plus the errors and warnings with the rule and the field involved. Enough to fix it first time instead of guessing.
HTTP/1.1 422 Unprocessable Content
{ "valid": false,
"xsd_checked": true,
"schematron_checked": true,
"errors": [ {
"regula": "ET-CO-12",
"mesaj": "Cod tarifar NC lipsă pentru bun.",
"camp": "bunuri[0].cod_tarifar"
} ], "warnings": [] }
Before you declare the first transport.
The rest, in the frequently asked questions and in the documentation.