E-invoicing API

E-invoicing API: Factur-X, ZUGFeRD and XRechnung from your invoice data

Send the invoice as JSON and get an e-invoice back: your branded PDF as PDF/A-3b with the EN 16931 XML embedded, or the XRechnung XML on its own. Every file is validated with the official rules before it is delivered.

  • Validated with KoSIT and veraPDF
  • CII and UBL
  • Rendered in the EU

What is an e-invoicing API?

An e-invoicing API turns invoice data into an invoice that software can read. Your application sends seller, buyer, lines and VAT as JSON; the API builds the structured XML of the European standard EN 16931, checks it against the official rules, and either embeds it in your invoice PDF (Factur-X, ZUGFeRD) or returns it on its own (XRechnung). The recipient's accounting software reads the XML; people read the PDF.

E-invoicing API key facts
Endpointseinvoice on any PDF render, for example POST https://api.dynamicdocumentapi.com/v1/pdf/from-template; POST /v1/einvoices for the XML alone
Hybrid PDFFactur-X / ZUGFeRD: PDF/A-3b with embedded UN/CEFACT CII XML; with the XRECHNUNG profile, an embedded XRechnung 3.0 file
XML onlyXRechnung or EN 16931 in CII (UN/CEFACT D16B) or UBL 2.1
ProfilesMINIMUM, BASIC_WL, BASIC, EN16931, EXTENDED, XRECHNUNG
ValidationEvery file before delivery: the KoSIT validator for XRechnung, EN 16931 and Factur-X rules, veraPDF for PDF/A. The report comes back with the render
TotalsLine amounts, VAT breakdown and totals computed by the EN 16931 rules and handed to your template
RenderingIn the EU (Germany), from your own template, HTML, URL or Markdown
PriceIncluded from the Growth plan: €47/month billed annually (€59 monthly) for 15,000 renders. The e-invoice inside a PDF adds 0 renders; an XML export is 1

Create a Factur-X or ZUGFeRD invoice in one request

Add einvoice to a normal PDF render. The invoice model sits in your template data, and invoice_path points at it, so the page and the XML use the same numbers. The engine renders the page, generates and validates the XML, converts the PDF to PDF/A-3b, embeds the XML and checks the finished file with veraPDF. Start from the E-Rechnung template in the gallery, which prints the computed amounts and works with every profile.

curl https://api.dynamicdocumentapi.com/v1/pdf/from-template \
  -H "Authorization: Bearer $DYNAMIC_DOCUMENT_API_KEY" \
  -H "Idempotency-Key: R-2026-0042" \
  -H "Content-Type: application/json" \
  -d '{
    "template_id": "tpl_einvoice",
    "data": {
      "invoice": {
        "number": "R-2026-0042",
        "issue_date": "2026-09-23",
        "due_date": "2026-10-23",
        "currency": "EUR",
        "buyer_reference": "PO-4711",
        "delivery": { "date": "2026-09-22" },
        "seller": {
          "name": "Example GmbH", "vat_id": "DE123456789",
          "electronic_address": { "id": "invoices@example.com", "scheme": "EM" },
          "address": { "line1": "Beispielstraße 1", "city": "Berlin", "postcode": "10115", "country": "DE" }
        },
        "buyer": {
          "name": "Customer AG", "vat_id": "DE987654321",
          "electronic_address": { "id": "ap@customer.example", "scheme": "EM" },
          "address": { "line1": "Marktplatz 5", "city": "München", "postcode": "80331", "country": "DE" }
        },
        "payment": { "means_code": "58", "credit_transfers": [{ "account_id": "DE02120300000000202051" }] },
        "lines": [
          { "quantity": "10", "unit": "HUR", "price": { "net": "100.00" },
            "tax": { "category": "S", "rate": "19" }, "item": { "name": "Consulting" } }
        ]
      }
    },
    "einvoice": { "profile": "EN16931", "invoice_path": "invoice" },
    "filename": "{{ data.invoice.number }}.pdf",
    "delivery": "binary"
  }' \
  --output R-2026-0042.pdf
// Node.js 18+: render the invoice as a Factur-X / ZUGFeRD PDF
export async function renderEInvoice(invoice) {
  const res = await fetch("https://api.dynamicdocumentapi.com/v1/pdf/from-template", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.DYNAMIC_DOCUMENT_API_KEY}`,
      "Idempotency-Key": invoice.number, // safe to retry
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      template_id: "tpl_einvoice",
      data: { invoice },
      einvoice: { profile: "EN16931", invoice_path: "invoice" },
      filename: `${invoice.number}.pdf`,
      delivery: "binary",
    }),
  });
  if (!res.ok) throw new Error(await res.text());
  return Buffer.from(await res.arrayBuffer());
}
import os
import requests

def render_einvoice(invoice: dict) -> bytes:
    res = requests.post(
        "https://api.dynamicdocumentapi.com/v1/pdf/from-template",
        headers={
            "Authorization": f"Bearer {os.environ['DYNAMIC_DOCUMENT_API_KEY']}",
            "Idempotency-Key": invoice["number"],  # safe to retry
        },
        json={
            "template_id": "tpl_einvoice",
            "data": {"invoice": invoice},
            "einvoice": {"profile": "EN16931", "invoice_path": "invoice"},
            "filename": f"{invoice['number']}.pdf",
            "delivery": "binary",
        },
        timeout=130,
    )
    res.raise_for_status()
    return res.content
<?php
function renderEInvoice(array $invoice): string
{
    $ch = curl_init('https://api.dynamicdocumentapi.com/v1/pdf/from-template');
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . getenv('DYNAMIC_DOCUMENT_API_KEY'),
            'Idempotency-Key: ' . $invoice['number'], // safe to retry
            'Content-Type: application/json',
        ],
        CURLOPT_POSTFIELDS     => json_encode([
            'template_id' => 'tpl_einvoice',
            'data'        => ['invoice' => $invoice],
            'einvoice'    => ['profile' => 'EN16931', 'invoice_path' => 'invoice'],
            'filename'    => $invoice['number'] . '.pdf',
            'delivery'    => 'binary',
        ]),
    ]);
    return curl_exec($ch); // PDF/A-3b with the XML embedded
}

Totals are not in the request: the engine computes them. If the invoice breaks a rule of the profile, the request fails with 422 einvoice_invalid or einvoice_validation_failed and a list of findings that point into your invoice, for example invoice.seller.contact. Failed renders are not billed. A template can also store the e-invoice as its default, so callers only send the data.

XRechnung for German public-sector buyers

XRechnung is the standard format for invoices to German public authorities. Which other EN 16931 formats an invoice portal accepts differs between federal, state and municipal buyers, so check with the authority if you are unsure. Use the XRECHNUNG profile: as an XML file on its own, in CII or UBL, or embedded in your PDF as xrechnung.xml. The profile adds its own required fields, which the API checks before any XML is written:

  • buyer_reference (BT-10): the buyer's Leitweg-ID
  • seller.contact with name, phone and email
  • electronic_address for seller and buyer, for example scheme 0204 for a Leitweg-ID
  • payment with a payment means code, such as 58 for a SEPA credit transfer, and the account
# invoice shortened here; the complete model is linked below
curl https://api.dynamicdocumentapi.com/v1/einvoices \
  -H "Authorization: Bearer $DYNAMIC_DOCUMENT_API_KEY" \
  -H "Idempotency-Key: xrechnung-XR-2026-0007" \
  -H "Content-Type: application/json" \
  -d '{
    "profile": "XRECHNUNG",
    "syntax": "ubl",
    "invoice": { "number": "XR-2026-0007", "buyer_reference": "04011000-12345-34", "…": "…" },
    "delivery": { "type": "binary" }
  }' \
  -o XR-2026-0007.xml

The complete invoice model in the docs is a valid XRechnung for a German federal authority, with every field explained. In UBL, credit notes (type code 381) use the CreditNote root element.

Pick the profile your recipient asks for

ProfileWhat it carriesSyntaxes
EN16931The complete invoice. The right default for B2B invoices in the EUCII, UBL
XRECHNUNGThe complete invoice plus the German XRechnung 3.0 rules; the standard for German public-sector buyersCII, UBL
EXTENDEDThe complete invoice with the additional fields of the Factur-X extended profileCII
BASICA basic subset of the invoice linesCII
BASIC_WL, MINIMUMHeader data and totals only, no lines. Not an e-invoice under the German B2B rules; use them only where a booking aid is enoughCII

Hybrid PDFs always embed CII; UBL is available for the standalone XML.

One invoice model, the amounts computed for you

The invoice model is JSON for the EN 16931 semantic model, with one field per business term. You describe what was sold; the engine does the arithmetic the standard prescribes, so the page and the XML can't disagree.

Totals that match the XML to the cent

Line amounts, the VAT breakdown per category and rate, and the document totals are computed with the EN 16931 rules and passed to your template as render.invoice. Print those values instead of calculating in the template.

{{ render.invoice.totals.due_payable
   | format_currency("EUR", "de-DE") }}
→ 1.190,00 €

Every VAT case of the standard

Standard and zero rates, exemptions, reverse charge, intra-community supplies, exports and supplies not subject to VAT, each with the exemption reason the rules require.

"tax": { "category": "AE", "rate": "0" }
reverse charge, with seller and buyer VAT IDs

Credit notes and corrections

Set the document type, reference the original invoice, and keep quantities and prices positive: the type code makes the document a credit.

"type_code": "381",
"preceding_invoices": [{ "number": "R-2026-0042" }]

An e-invoice by default

Store the profile and the data path in the template's options, in the dashboard or through the API. Every render of that template is then a Factur-X / ZUGFeRD PDF, and callers only send the data. Every invoice template in the gallery ships this way.

Month-end runs in one batch

In a batch, each item's own data holds its own invoice, so one request produces a validated e-invoice per customer.

Test mode that is honest about it

Test renders are free and validated like live ones. Test PDFs carry a TEST watermark and test XML a note saying it is not a valid invoice, so nothing you try can be mistaken for a real invoice.

A validation report with every render

Each e-invoice render carries a conformance report from the unmodified official validators: veraPDF for the PDF/A file and the KoSIT validator for the XML. When a rule fails, the finding names the rule and points at the field in your invoice:

{
  "conformance": {
    "pdfa":     { "level": "3b", "status": "passed", "validator": "veraPDF 1.30.2" },
    "einvoice": { "profile": "XRECHNUNG", "syntax": "cii", "status": "passed",
                  "validator": "KoSIT Validator 1.6.3", "errors": [], "warnings": [] }
  }
}
// a failed rule: { "rule": "BR-DE-2", "location": "invoice.seller.contact", … }

If a validator doesn't answer in time, the render still completes: the report's status is unavailable and a warning says the file is unvalidated. The dashboard shows the same report on the render's page. See the validation report for every field.

Who needs e-invoices, and what we take care of

  • Germany, B2B. Since January 1, 2025, businesses in Germany must be able to receive e-invoices for domestic B2B sales. From 2027, businesses with more than €800,000 in prior-year turnover must issue them; from 2028, in principle all businesses. Exempt are, among others, small-amount invoices up to €250, travel tickets and small businesses under § 19 UStG. XRechnung and ZUGFeRD from version 2.0.1 qualify, except the MINIMUM and BASIC WL profiles; a plain PDF is not an e-invoice.
  • Public-sector buyers. Authorities in the EU accept invoices that follow EN 16931; for German authorities, XRechnung is the standard.
  • What we guarantee. Technical format conformance, checked against the official schemas and schematron rules before delivery.
  • What stays with you. The content and tax correctness of each invoice, and its transmission: we don't connect to Peppol or to government invoice portals, so hand the XML to your Peppol access point or the authority's portal. Deliver the PDF from your system, or have each one emailed from your own email provider account on Growth and above (email delivery). Check deadlines and exemptions with your tax advisor.

What an e-invoice costs

Growth

€47 / month

15,000 renders per month, billed annually (€59 billed monthly). E-invoicing, PDF/A and email delivery included.

Per invoice

+0

The e-invoice inside a PDF adds nothing to the render count. An XML export with /v1/einvoices is one render; test and failed renders are free.

Free and Starter don't include e-invoicing, but you can design and render the invoice layout there: templates with a default e-invoice receive the computed amounts on every plan. See all plans.

FAQ

E-invoicing API: frequently asked questions

Is ZUGFeRD the same as Factur-X?

Technically, yes. Since ZUGFeRD 2.1, ZUGFeRD and Factur-X describe the same hybrid format: a PDF/A-3 invoice with embedded UN/CEFACT CII XML. The API produces it with the profile you choose, and the XRECHNUNG profile embeds an XRechnung 3.0 file instead.

Does the API calculate VAT and totals?

For e-invoices, yes. You send the lines, allowances and charges; the engine computes line amounts, the VAT breakdown and the document totals with the EN 16931 rules and passes them to your template, so the visible invoice matches the XML to the cent. Tax rates, VAT categories and invoice numbers still come from your system.

Does the API send e-invoices to my customers?

It can email the PDF from your own email provider account on the Growth plan and above, or return it to your system as a file or signed link. It does not connect to Peppol or to government invoice portals: transmission, for example through a certified platform in France or the portals of German public authorities, stays with you.

Can I test e-invoices before I send real ones?

Yes. Renders with a test key are free and validated like live renders. Test PDFs carry a TEST watermark, and test XML carries a note that marks it as a test invoice. Test renders need a plan that includes e-invoicing; templates with a default e-invoice, such as the invoice templates in the gallery, receive the computed amounts on every plan, so you can build the invoice layout first.

Who is responsible for the content of the invoice?

You are. We guarantee technical format conformance, checked against the official schemas and schematron rules. The invoice's content, its tax correctness and its transmission remain your responsibility.

Which plans include e-invoicing?

Growth, Pro, Scale and Enterprise. Growth costs €47 a month billed annually (€59 billed monthly) for 15,000 renders. Embedding an e-invoice in a PDF adds nothing to the render count; a standalone XML export counts as one render; test and failed renders are free.

Build your e-invoice template

Design and render the invoice layout on the free plan; embedding e-invoices starts with Growth.

Start free