oneapi
Sign in
Anaf v1 / Declarații D

Derive a draft from an existing source

Builds a DRAFT return from what you already hold: D394 and D390 from e-Factura invoices, D710 from two D100 returns (the original and the corrected one). The draft then goes to build, after you check it.

POST
https://oneapi.ro/api/anaf/v1/declaratii/deriva/{form}

Path parameters

NameTypeDescriptionExample
formrequired string Code of the form derived from data already submitted.

Request body

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

NameTypeDescriptionAccepted values
declarantoptional object The declarant header, with the keys {form}/build accepts: cui, den, adresa, nume, prenume, functie, telefon, fax, mail (plus caen for D394). An unknown key — say denumire instead of den — returns 422 listing the accepted keys. Whatever stays empty shows up in warnings.
facturioptional string[] | object[] For D390/D394: the batch of e-Factura (CIUS-RO) invoices to derive from. An item is either the XML itself (text or base64) or the object {id, xml}. Not sent for D710 — there the body is {initial, corectat}.
lunaoptional integer For D390/D394: the reported month, 1–12. Not sent for D710.
anoptional integer For D390/D394: the reported year, 2016 or later. Not sent for D710.
initialoptional string For D710: the D100 as filed, raw XML or base64.
corectatoptional string For D710: the corrected D100, raw XML or base64.
D394 from invoices Request body
{
    "luna": 9,
    "an": 2026,
    "declarant": {
        "cui": "990000005",
        "den": "Exemplu Furnizor SRL"
    },
    "facturi": [
        "@efactura.xml"
    ]
}

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

A D390 from an intra-community supply Request body
{
    "luna": 9,
    "an": 2026,
    "declarant": {
        "cui": "990000005",
        "den": "Exemplu Furnizor SRL"
    },
    "facturi": [
        "@efactura-intracomunitara.xml"
    ]
}

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

A D710 from two D100 returns Request body
{
    "initial": "@d100.xml",
    "corectat": "@d100-rectificat.xml"
}

In this example, @d100.xml, @d100-rectificat.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

  • Returns a DRAFT declaration in the shape that {form}/build accepts, derived from data you already hold. Two sources, depending on the form: D390 and D394 are derived from a batch of e-Factura invoices (CIUS-RO), while D710 is derived from two D100 declarations — the one you filed and the corrected one.
  • D390: keeps only invoices to intra-community customers (an EU country ≠ RO, with a VAT id), grouped by (VAT id, type) with the net base in whole lei. CIUS-RO does not tell goods from services, so the type defaults to L (supplies) — set it per row (L/T/A/P/S/R).
  • D394: keeps domestic B2B invoices (a RO customer with a VAT id), grouped by (CUI, VAT rate) with base + VAT. The header (representative, preparer, CAEN, phone) cannot be derived from invoices and remains to be completed — see warnings.
  • D710 (amending a D100): the body is {initial, corectat} — the two D100 declarations (XML or base64), the one you filed and the corrected one. Obligations are matched on (obligation code, budget code) and the amounts go into D710's _i/_c pairs. The mapping is 1:1, no heuristics: D710 carries exactly the same amounts as D100, just split across two columns. Only the obligations whose amounts actually differ stay in the draft (that is what an amending return means); nr_neschimbate tells you how many were left untouched. Derivation is refused outright if the two declarations cover different periods, belong to different CUIs, or differ in nothing at all.
  • It is a draft to review, not a final declaration: check the rows and warnings, complete the flagged fields, then send the result to POST /anaf/v1/declaratii/{form}/build. An invalid invoice in the batch is skipped with a warning, it does not stop the derivation.
  • Zero retention and no SPV submission — nothing is filed or definitively built here.

What it is for

  • Quick-starting a D390/D394 from the month's invoices, without re-keying partners and bases by hand.
  • Amending a D100 you already filed: hand over the old declaration and the correct version, get back the D710 with its "initial"/"corrected" columns already filled in, instead of transcribing them by hand.

Response structure

FieldTypeDescription
data.formular string The derived form code.
data.draft object The business JSON (draft) — the same shape {form}/build accepts.
data.draft.luna integer The month the value refers to.
data.draft.an integer The year the value refers to.
data.draft.tip_D394 string
data.draft.declarant.cui string Tax identification number, without the RO prefix.
data.draft.declarant.den string
data.draft.parteneri[].tip string
data.draft.parteneri[].tip_partener integer
data.draft.parteneri[].cota integer
data.draft.parteneri[].cui string Tax identification number, without the RO prefix.
data.draft.parteneri[].den string
data.draft.parteneri[].nr_facturi integer
data.draft.parteneri[].baza integer
data.draft.parteneri[].tva integer
data.warnings[] array Warnings: heuristics applied (type/partner type), skipped invoices, fields to complete.
data.warnings[].cod string Code from the source code list — the key you filter on.
data.warnings[].mesaj string
data.warnings[].camp string
data.nr_facturi integer How many invoices from the batch contributed to the draft.
data.nr_randuri integer How many rows (operations/partners) the draft has.
meta.generat_la string When the response was built (ISO 8601).
meta.note string

Response examples

body: {"luna": 9, "an": 2026, "declarant": {"cui": "990000005", "den": "Exemplu Furnizor SRL"}, "facturi": ["@efactura.xml"]}

POSThttps://oneapi.ro/api/anaf/v1/declaratii/deriva/D394
{
    "data": {
        "formular": "D394",
        "draft": {
            "luna": 9,
            "an": 2026,
            "tip_D394": "L",
            "declarant": {
                "cui": "990000005",
                "den": "Exemplu Furnizor SRL"
            },
            "parteneri": [
                {
                    "tip": "L",
                    "tip_partener": 1,
                    "cota": 21,
                    "cui": "990000072",
                    "den": "Exemplu Client SRL",
                    "nr_facturi": 1,
                    "baza": 700,
                    "tva": 147
                }
            ]
        },
        "warnings": [
            {
                "cod": "atentie",
                "mesaj": "Toate rândurile au fost derivate cu tip „L\" (livrări) și tip_partener „1\" (persoană înregistrată în scopuri de TVA). Verifică pentru fiecare partener tipul operațiunii (A/L/C/V/LS/AS/AI/N) și tipul de partener (1–4).",
                "camp": "parteneri"
            }
        ],
        "nr_facturi": 1,
        "nr_randuri": 1
    },
    "meta": {
        "generat_la": "2026-10-06T23: 59: 42+03: 00",
        "note": "Rezultatul e un DRAFT de revizuit, nu o declarație finală: verifică rândurile și avertismentele, completează câmpurile marcate, apoi trimite draftul la POST /anaf/v1/declaratii/D394/build. Nu s-a depus și nu s-a construit nimic definitiv."
    }
}

Error codes

CodeSlugWhen it occurs
401neautentificatToken missing, invalid, expired or revoked.
403feature_indisponibilThe current plan does not include the feature the route depends on.
404negasitNon-derivable form (only D390 and D394).
422xml_invalidInvalid luna/an or missing facturi.
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": "Invalid luna/an or missing facturi.",
        "camp": "form",
        "request_id": "0199c1f0-6e1a-7c3d-9b2f-4a8e5d1c7b04"
    }
}