Eine ZUGFeRD-CLI validiert E-Rechnungen skriptbar über die Kommandozeile – lokal, in CI/CD oder per API-Aufruf, ohne Browser-Upload.
Dafür gibt es drei praktikable Wege, die sich in einem Punkt deutlich unterscheiden: ob eine Java-Laufzeitumgebung auf der Maschine liegen muss. Diese Seite zeigt alle drei mit lauffähigen Beispielen und ordnet ein, wann welcher sinnvoll ist.
Welche Optionen gibt es?
| Weg | Voraussetzungen | Offline-fähig | Ausgabeformat | Typischer Einsatz |
|---|---|---|---|---|
| curl + REST API | curl, base64 |
Nein | JSON | CI/CD, Skripte, schlanke Container |
| Mustang-CLI | Java ≥ 21, JAR-Download | Ja | XML-Report | Lokale Prüfung, Daten dürfen das Netz nicht verlassen |
| MCP-Client | Node.js ≥ 18 | Nein | JSON (MCP-Tools) | KI-Agenten in Cursor, Windsurf, Claude |
Kurz gefasst: curl ist der schnellste Weg in eine Pipeline, Mustang-CLI der einzige echte Offline-Weg, und der MCP-Client der Weg, wenn ein KI-Agent die Prüfung selbst auslösen soll.
ZUGFeRD und XRechnung per curl validieren
Die REST API des ZUGFeRD Validators nimmt den Dateiinhalt base64-kodiert entgegen und antwortet mit strukturiertem JSON. Auf der Maschine muss dafür kein Java liegen — curl und ein Base64-Kommando reichen. Im Hintergrund prüft dieselbe Engine wie beim Online-Validator: das Mustang Project und das KoSIT-Validierungstool gegen die Norm EN 16931 und die deutschen Geschäftsregeln (BR-DE).
Beispiel-Request
Die Datei wird zuerst base64-kodiert und dann als file_content übergeben. file_type ist xml für eine XRechnung oder CII-XML und pdf für ein ZUGFeRD- oder Factur-X-PDF. Der API-Key gehört in den X-Api-Key-Header.
# XRechnung-XML in einem Durchgang prüfen (macOS/Linux) B64=$(base64 < rechnung.xml | tr -d '\n') curl -X POST https://api.zugferd-validator.de/v1/validate \ -H "X-Api-Key: zv_demo_public_zugferd_2026" \ -H "Content-Type: application/json" \ -d "{\"file_content\":\"$B64\",\"file_type\":\"xml\"}"
Für ein ZUGFeRD-PDF ändert sich nur die Quelldatei und file_type — das eingebettete XML extrahiert der Validator selbst und erkennt auch das Profil (MINIMUM bis EXTENDED) automatisch:
# ZUGFeRD-PDF statt XML B64=$(base64 < rechnung.pdf | tr -d '\n') # … dieselbe Anfrage, aber: "file_type":"pdf"
zv_demo_public_zugferd_2026 funktioniert sofort ohne Anmeldung (1 Anfrage pro Tag und IP) — gut zum Ausprobieren, zu wenig für eine Pipeline. Ein kostenloser API-Key bringt 20 Validierungen pro Woche.Das JSON-Ergebnis lesen
Die Antwort ist bewusst maschinenlesbar, kein Freitext. valid trägt das Gesamtergebnis, errors und warnings listen jeden Punkt mit Regel-ID, betroffenem BT-Feld, Korrekturvorschlag und XPath:
{
"valid": false,
"format": "ZUGFeRD 2.4.0",
"profile": "EN16931",
"summary": "1 Fehler gefunden",
"errors": [{
"severity": "error",
"rule_id": "BR-DE-1",
"field": "BG-16",
"message": "PAYMENT INSTRUCTIONS (BG-16) fehlen.",
"fix_suggestion": "Füge die Gruppe BG-16 hinzu: mindestens die Zahlungsart ram:SpecifiedTradeSettlementPaymentMeans/ram:TypeCode (BT-81).",
"xpath": "//ram:ApplicableHeaderTradeSettlement/ram:SpecifiedTradeSettlementPaymentMeans"
}]
}
Wichtig für die Auswertung: Warnungen allein setzen valid nicht auf false. Was hinter einer Regel-ID wie BR-DE-1 steckt, steht im Fehlercode-Lexikon — jede ID ist dort mit Bedeutung, Feld und Korrektur dokumentiert.
In CI/CD einbauen
Für eine Pipeline braucht es genau zwei Dinge: einen Exit-Code, der den Build stoppt, und eine Fehlerausgabe, die im Log brauchbar ist. Beides liefert jq aus der JSON-Antwort. Das folgende Skript bricht bei jeder nicht konformen Rechnung ab:
#!/usr/bin/env bash # validate.sh — bricht ab, sobald eine Rechnung nicht konform ist set -euo pipefail B64=$(base64 < "$1" | tr -d '\n') RESULT=$(curl -sS -X POST https://api.zugferd-validator.de/v1/validate \ -H "X-Api-Key: $ZUGFERD_API_KEY" \ -H "Content-Type: application/json" \ -d "{\"file_content\":\"$B64\",\"file_type\":\"xml\"}") if [ "$(echo "$RESULT" | jq -r '.valid')" = "true" ]; then echo "OK: $1 ist konform zu EN 16931" else echo "FEHLER in $1:" echo "$RESULT" | jq -r '.errors[] | " \(.rule_id) (\(.field)): \(.message)\n Fix: \(.fix_suggestion)"' exit 1 fi
Der API-Key kommt als Secret aus der CI-Umgebung, nie ins Repository. In einer GitHub-Action ist der Aufruf danach ein Einzeiler:
# .github/workflows/e-rechnung.yml (Auszug) - name: E-Rechnung gegen EN 16931 prüfen env: ZUGFERD_API_KEY: ${{ secrets.ZUGFERD_API_KEY }} run: ./validate.sh fixtures/rechnung.xml
Mustang-CLI lokal nutzen (der Java-Weg)
Die Mustang-CLI ist der De-facto-Standard für lokale ZUGFeRD-Validierung — und die quelloffene Engine, die auch im Hintergrund dieser API arbeitet. Wer sie direkt nutzt, validiert vollständig offline, übernimmt aber Installation, Java-Betrieb und Aktualisierung der Regelsets selbst.
Installation und Aufruf
Voraussetzung ist eine Java-Laufzeitumgebung ab Version 21. Das JAR liegt im Maven-Repository beziehungsweise bei den GitHub-Releases des Mustang Projects:
# Mustang-CLI herunterladen curl -L -o Mustang-CLI-2.22.0.jar \ https://repo1.maven.org/maven2/org/mustangproject/validator/2.22.0/validator-2.22.0-shaded.jar # Java-Version prüfen (muss 21+ sein) java -version # Rechnung validieren — Ergebnis ist ein XML-Report auf stdout java -jar Mustang-CLI-2.22.0.jar --action=validate --source=rechnung.xml
Der Aufruf funktioniert für PDF und XML gleichermaßen; die Quelldatei wird über --source als Pfad übergeben. Anders als bei der API ist die Ausgabe ein XML-Report — für eine Pipeline muss der erst geparst werden, und die Regel-IDs bringen keine deutschen Korrekturvorschläge mit.
Wann lohnt sich lokal, wann die API?
Lokal (Mustang-CLI) ist die richtige Wahl, wenn Rechnungsdaten das eigene Netz aus rechtlichen oder organisatorischen Gründen nicht verlassen dürfen, wenn ohne Internetverbindung geprüft werden muss oder wenn sehr große Volumina ohne Kontingentgrenze anfallen. Der Preis dafür: Java-Runtime im Container, JAR-Updates bei neuen Regelständen und ein eigener Parser für den XML-Report.
Die API lohnt sich, wenn der Build schlank bleiben soll und das Ergebnis direkt verwertbar sein muss. Kein Java, kein JAR, keine Regelpflege — dafür JSON mit Regel-ID, Feld, XPath und konkretem Korrekturvorschlag pro Fehler. Die Regelsets werden serverseitig aktuell gehalten.
MCP-Client für KI-Agenten
Soll nicht ein Skript, sondern ein KI-Agent die Prüfung auslösen, gibt es den MCP-Client als npm-Paket. Er spricht dieselbe API, stellt sie aber als Model-Context-Protocol-Tools bereit, die Clients wie Claude, Cursor oder Windsurf selbstständig aufrufen können. Voraussetzung ist Node.js ab Version 18, Java wird nicht gebraucht.
# Global installieren … npm install -g zugferd-mcp-client # … oder ohne Installation direkt ausführen npx zugferd-mcp-client
Die Einbindung erfolgt über die MCP-Konfiguration des jeweiligen Clients. Das Binary heißt zugferd-mcp, der API-Key kommt als Umgebungsvariable:
{
"mcpServers": {
"zugferd": {
"command": "zugferd-mcp",
"env": { "ZUGFERD_API_KEY": "zv_…" }
}
}
}
Danach stehen dem Agenten vier Tools zur Verfügung: validate_invoice (prüfen), extract_xml (XML aus einer PDF holen), check_consistency (PDF-Anzeige gegen XML-Daten abgleichen) und create_invoice (valide E-Rechnung aus strukturierten Daten erzeugen).