fakturai blog

Python & Node SDK

Generate German e-invoices with Python and Node.js (API integration)

Short answer: send a compact JSON payload via HTTP POST to the fakturai REST API and receive an EN 16931-compliant ZUGFeRD/Factur-X or XRechnung file back — no XML knowledge, no local libraries, no manual namespace declarations. The API checks the generated file against a KoSIT-aligned accept gate before returning it.

Why API instead of a local library?

Local XML libraries for ZUGFeRD or XRechnung require deep format knowledge: EN 16931 BT/BG codes, namespace declarations, Schematron rules, profile specifics. The API abstracts all of that:

Python example (httpx / requests)

import httpx, pathlib

payload = {
  "invoiceNumber": "INV-2026-0042",
  "issueDate": "2026-06-16",
  "seller": {
    "name": "Sample GmbH", "street": "Musterstraße 1", "city": "Berlin",
    "postalCode": "10115", "countryCode": "DE", "vatId": "DE123456789"
  },
  "buyer": {
    "name": "Client AG", "street": "Clientweg 2", "city": "Munich",
    "postalCode": "80331", "countryCode": "DE"
  },
  "lines": [{"description": "Consulting", "quantity": 2, "unitCode": "C62",
              "unitPrice": 50.0, "vatRate": 19.0}],
  "currency": "EUR",
  "format": "zugferd"   # or "xrechnung"
}
resp = httpx.post(
    "https://api.fakturai.de/v1/invoices",
    json=payload,
    headers={"Authorization": "Bearer YOUR_API_KEY"},
)
resp.raise_for_status()
pathlib.Path("invoice.pdf").write_bytes(resp.content)

For requests, replace httpx.post with requests.post — the payload is identical.

Node.js / TypeScript example (fetch)

import fs from "fs/promises";

const payload = {
  invoiceNumber: "INV-2026-0042", issueDate: "2026-06-16",
  seller: { name: "Sample GmbH", street: "Musterstraße 1", city: "Berlin",
            postalCode: "10115", countryCode: "DE", vatId: "DE123456789" },
  buyer:  { name: "Client AG",   street: "Clientweg 2",   city: "Munich",
            postalCode: "80331", countryCode: "DE" },
  lines: [{ description: "Consulting", quantity: 2, unitCode: "C62",
            unitPrice: 50.0, vatRate: 19.0 }],
  currency: "EUR",
  format: "zugferd",   // or "xrechnung"
};
const res = await fetch("https://api.fakturai.de/v1/invoices", {
  method: "POST",
  headers: { "Content-Type": "application/json", Authorization: "Bearer YOUR_API_KEY" },
  body: JSON.stringify(payload),
});
if (!res.ok) throw new Error(`API error ${res.status}: ${await res.text()}`);
await fs.writeFile("invoice.pdf", Buffer.from(await res.arrayBuffer()));

The payload is the same JSON structure regardless of language. In TypeScript, add a type definition for the payload; the result is a Buffer / ArrayBuffer.

Key mandatory fields

MCP integration for AI agents

Alongside the REST API, a MCP server exposes the same generate-and-check logic as a tool call. AI agents and MCP clients can generate e-invoices without crafting HTTP manually. See create e-invoices per API & MCP.

What fakturai does not replace

fakturai generates and checks the technical format and structural compliance per EN 16931 with a KoSIT-aligned accept gate. The content and tax correctness of the JSON payload, GoBD-compliant archiving and accounting treatment remain your responsibility. fakturai is not tax advice and makes no legal, tax or delivery guarantees.

Next step

Free German e-invoice validator · Create an API key · API docs

Related: API & MCP creation guide · E-invoice example (XML) · XRechnung validation errors

Free validator · Create API key · API docs