Zum Inhalt springen
xmoo.app

API · E-Rechnung

xmoo E-Invoice API

Europäische E-Rechnungen prüfen, auslesen, umwandeln und darstellen – XRechnung, ZUGFeRD, Factur-X und jede Rechnung nach EN 16931 in UBL oder CII – mit einem REST-Aufruf.

Was sie kann

Rechnungen werden nur im Arbeitsspeicher verarbeitet und nie gespeichert. Die API läuft auf einem Server in Helsinki, Finnland (EU), mit demselben Kern wie die kostenlosen Browser-Tools hier, der E-Rechnung-Viewer und der E-Rechnung-Konverter.

Die Dokumentation ist auf Englisch maßgeblich: E-Invoice API (English). Feldnamen und Standardtexte der API sind englisch, mit lang=de kommen die Texte auf Deutsch.

Zugang

Die API wird über RapidAPI angeboten. Dort wählst du einen Tarif, bekommst deinen Schlüssel und den Hostnamen für deine Anfragen; abgerechnet wird ebenfalls über RapidAPI: xmoo E-Invoice API bei RapidAPI. Fragen: julian@haag-automation.com.

Jede Anfrage trägt zwei Köpfe aus deinem RapidAPI-Konto:

x-rapidapi-key: <dein Schlüssel>
x-rapidapi-host: <Hostname aus dem Eintrag>

Die Beispiele unten erwarten beides in den Shell-Variablen RAPIDAPI_KEY und RAPIDAPI_HOST.

Endpunkte

EndpunktZweckAntwort
POST /v1/detectFormat, Syntax, Spezifikation und Profil; welche Regelwerke geltenJSON
POST /v1/validatePrüfbericht mit allen Meldungen und Summenkontrolle (BR-CO-10 bis 16)JSON
POST /v1/parseAlle Geschäftsbegriffe der EN 16931 als JSONJSON
POST /v1/convert?to=…Umwandeln in xrechnung-ubl, xrechnung-cii, zugferd (XML) oder zugferd-pdf (PDF/A-3)JSON mit der Datei als Base64
POST /v1/renderLesbares A4-PDF der RechnungPDF
GET /v1/formatsUnterstützte Formate, Regelwerke und ZieleJSON

Die maschinenlesbare Beschreibung liegt unter api.xmoo.app/openapi.json (OpenAPI 3.0).

Rechnung schicken

Schick einen JSON-Body mit der Datei (XML oder PDF) als Base64 in document. Das ist der empfohlene Weg und geht bei jedem Endpunkt:

base64 -w0 rechnung.xml | jq -Rs '{document: .}' |
curl -s -X POST "https://$RAPIDAPI_HOST/v1/validate" \
  -H "x-rapidapi-key: $RAPIDAPI_KEY" \
  -H "x-rapidapi-host: $RAPIDAPI_HOST" \
  -H "Content-Type: application/json" \
  --data-binary @-

Dasselbe in Python:

import base64, os, requests

with open("rechnung.pdf", "rb") as f:
    body = {"document": base64.b64encode(f.read()).decode()}

r = requests.post(f"https://{os.environ['RAPIDAPI_HOST']}/v1/validate", json=body, headers={
    "x-rapidapi-key": os.environ["RAPIDAPI_KEY"],
    "x-rapidapi-host": os.environ["RAPIDAPI_HOST"],
})
bericht = r.json()
print(bericht["valid"], bericht["summary"])

Die API nimmt die Datei auch roh als Body an (Content-Type: application/xml oder application/pdf); Optionen stehen dann in der Adresse. Weitere Felder des JSON-Bodys: to (Zielformat bei /v1/convert), additions (siehe unten) und lang.

Sprache

Feldnamen sind immer englisch. Beschreibende Texte – Änderungen, Verluste, Hinweise und Fehlermeldungen – sind standardmäßig englisch, mit lang=de deutsch. Regeltexte kommen wörtlich aus den offiziellen Artefakten: die der EN 16931 und von ZUGFeRD / Factur-X auf Englisch, die der XRechnung-Regeln der KoSIT (BR-DE-…) auf Deutsch.

Beispiele

Die Antworten unten sind echte Antworten der API (wo vermerkt gekürzt). Testdateien: die XRechnung-Testsuite der KoSIT und die ZUGFeRD-Beispiele des Mustang-Projekts. Ein Test bei uns schickt genau diese Anfragen und prüft, dass die Antworten noch stimmen.

Hybrides PDF erkennen

POST /v1/detect mit einem ZUGFeRD-PDF im Profil EN 16931:

{
  "source": "pdf",
  "syntax": "CII",
  "documentType": "invoice",
  "specification": "urn:cen.eu:en16931:2017",
  "profile": "EN 16931 (for ZUGFeRD: profile EN 16931)",
  "rulesets": [
    "schema-facturx-en16931",
    "facturx-en16931"
  ]
}

XRechnung prüfen

POST /v1/validate mit einer XRechnung 3.0 in UBL. Die Rechnung ist gültig; die KoSIT-Regeln geben einen Hinweis (Schwere info). Gekürzt auf die ersten beiden Summenprüfungen:

{
  "source": "xml",
  "syntax": "UBL",
  "documentType": "invoice",
  "specification": "urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0",
  "profile": "XRechnung 3.0",
  "rulesets": [
    "schema-ubl",
    "en16931-ubl",
    "xrechnung-ubl"
  ],
  "valid": true,
  "summary": {
    "errors": 0,
    "warnings": 0,
    "infos": 1
  },
  "reports": [
    {
      "ruleset": "schema-ubl",
      "title": "XML Schema UBL 2.1",
      "messages": []
    },
    {
      "ruleset": "en16931-ubl",
      "title": "EN 16931 (validation artefacts 1.3.17, UBL)",
      "messages": []
    },
    {
      "ruleset": "xrechnung-ubl",
      "title": "XRechnung 3.0 (KoSIT-Schematron 2.6.0, UBL)",
      "messages": [
        {
          "rule": "BR-DE-TMP-32",
          "severity": "info",
          "text": "Eine Rechnung sollte zur Angabe des Liefer-/Leistungsdatums entweder BT-72 \"Actual delivery date\", BG-14 \"Invoicing period\" oder in jeder Rechnungsposition BG-26 \"Invoice line period\" enthalten.",
          "location": "/Invoice[1]"
        }
      ]
    }
  ],
  "note": null,
  "totalsCheck": [
    {
      "rule": "BR-CO-10",
      "text": "Sum of invoice line net amount (BT-106) = sum of all line net amounts",
      "expected": 314.86,
      "actual": 314.86,
      "ok": true
    },
    {
      "rule": "BR-CO-13",
      "text": "Invoice total amount without VAT (BT-109) = sum of lines − allowances + charges",
      "expected": 314.86,
      "actual": 314.86,
      "ok": true
    }
  ]
}

valid ist true, wenn keine Meldung die Schwere error hat. Auch für ungültige Rechnungen kommt 200 – eine nicht bestandene Prüfung ist ein Ergebnis, kein Fehler.

Als JSON auslesen

POST /v1/parse, dieselbe Rechnung, gekürzt auf einige Felder. Beträge und Daten bleiben Zeichenketten genau wie in der Datei, damit durch Rundung nichts verloren geht:

{
  "source": "xml",
  "syntax": "UBL",
  "profile": "XRechnung 3.0",
  "invoice": {
    "number": "123456XX",
    "issueDate": "2016-04-04",
    "typeCode": "380",
    "currencyCode": "EUR",
    "buyerReference": "04011000-12345-03",
    "seller": {
      "name": "[Seller name]",
      "vatIdentifier": "DE 123456789",
      "address": {
        "city": "[Seller city]",
        "postCode": "12345",
        "countryCode": "DE"
      }
    },
    "totals": {
      "totalWithoutVat": "314.86",
      "totalVatAmount": "22.04",
      "totalWithVat": "336.9",
      "amountDueForPayment": "336.9"
    },
    "lines": [
      {
        "quantity": "1",
        "unitCode": "XPP",
        "netAmount": "288.79",
        "vatRate": "7",
        "itemName": "Zeitschrift [...]",
        "description": "Zeitschrift Inland"
      }
    ]
  },
  "unmapped": []
}

XRechnung in ZUGFeRD umwandeln

POST /v1/convert?to=zugferd mit derselben XRechnung. Die Antwort nennt jede Änderung und jeden Verlust und enthält die Prüfung des Ergebnisses; die Datei selbst steht in document.base64 (hier weggelassen):

{
  "target": "zugferd",
  "changes": [
    "Specification identifier (BT-24): urn:cen.eu:en16931:2017 instead of urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0"
  ],
  "losses": [],
  "ignoredAdditions": [],
  "validation": {
    "valid": true,
    "summary": {
      "errors": 0,
      "warnings": 1,
      "infos": 0
    }
  },
  "document": {
    "contentType": "application/xml",
    "filename": "invoice_zugferd.xml"
  }
}

Wenn Angaben fehlen

Eine XRechnung braucht Angaben, die einer ZUGFeRD-Rechnung fehlen können, etwa die Käuferreferenz (Leitweg-ID), elektronische Adressen und einen Ansprechpartner des Verkäufers. POST /v1/convert?to=xrechnung-ubl mit dem ZUGFeRD-PDF von oben antwortet mit 422 und nennt, was fehlt (gekürzt auf die ersten zwei von neun Feldern):

{
  "error": {
    "code": "additions_required",
    "message": "The target format requires data the document does not contain. Nothing is invented: send it as \"additions\".",
    "missing": [
      {
        "path": "buyerReference",
        "name": "Buyer reference / Leitweg-ID",
        "rule": "BR-DE-15",
        "help": "For invoices to German public authorities the Leitweg-ID, otherwise the reference your customer gave you.",
        "optional": false,
        "provided": false
      },
      {
        "path": "seller.electronicAddress",
        "name": "Seller email address for invoices",
        "rule": "PEPPOL-EN16931-R020",
        "help": null,
        "optional": false,
        "provided": false
      }
    ]
  }
}

Schick die Werte als additions, mit path als Schlüssel, und wiederhole die Anfrage. Vorhandene Angaben werden nie überschrieben; nicht benötigte Ergänzungen stehen in ignoredAdditions.

{
  "document": "<Base64>",
  "to": "xrechnung-ubl",
  "additions": {
    "buyerReference": "04011000-12345-03",
    "seller.electronicAddress": "rechnung@example.com",
    "payment.iban": "DE02120300000000202051"
  }
}

Fehler

Fehler kommen als JSON mit festem code und lesbarer message:

{"error": {"code": "not_an_e_invoice", "message": "…"}}
StatusCodeBedeutung
400empty, bad_json, missing_documentKeine Datei, ungültiges JSON oder kein Feld document
400invalid_target, invalid_lang, invalid_additionsUnbekanntes Zielformat oder unbekannte Sprache, Ergänzungen kein Objekt aus Zeichenketten
401unauthorizedAnfrage kam nicht über RapidAPI
404, 405not_found, method_not_allowedUnbekannter Endpunkt oder falsche HTTP-Methode
413too_largeAnfrage größer als 50 MB
422not_an_e_invoice, not_readableWeder UBL noch CII, oder ein PDF ohne eingebettete Rechnung
422doctype_not_allowedXML mit DOCTYPE- oder ENTITY-Deklaration wird aus Sicherheitsgründen abgelehnt
422additions_requiredDas Zielformat braucht Angaben – siehe missing
422not_convertible, already_target_formatUmwandlung nicht möglich oder nicht nötig
422result_not_validDie umgewandelte Rechnung besteht die offizielle Prüfung nicht und kommt deshalb nicht zurück (Bericht in validation)
503, 504busy, timeoutZu viele Anfragen gleichzeitig oder Bearbeitung länger als 30 s – später erneut versuchen
500internal_errorUnser Fehler; nach den Abrechnungsregeln von RapidAPI zählen Antworten ab Status 500 nicht

Regelwerke und Stände

RegelwerkStand
XML-SchemaUBL 2.1, UN/CEFACT CII D16B
EN-16931-Prüfregeln (CEN)1.3.17 (UBL und CII)
XRechnung (KoSIT-Schematron)XRechnung 3.0, Schematron 2.6.0
ZUGFeRD / Factur-XZUGFeRD 2.5.2 / Factur-X 1.09.2, Profile MINIMUM, BASIC WL, BASIC, EN 16931, EXTENDED

Rechnungen nach Peppol BIS Billing 3.0 werden gelesen und gegen EN 16931 geprüft. Erscheint ein neuer Stand eines Regelwerks, wird die API nachgezogen und diese Tabelle mit ihr.

Grenzen

Mit KI-Agenten (MCP)

RapidAPI stellt seine APIs auch als Werkzeuge für KI-Agenten über das Model Context Protocol (MCP) bereit. Mit deinem RapidAPI-Schlüssel kann ein Agent jeden Endpunkt als Werkzeug aufrufen; es gilt dein Tarif.

Datenschutz und Bedingungen

Rechnungen enthalten personenbezogene Daten. Wir verarbeiten sie nur, um deine Anfrage zu beantworten, im Arbeitsspeicher, und behalten nichts. Einzelheiten: Datenschutzhinweise der API und Auftragsverarbeitungsvertrag (Art. 28 DSGVO). Die Nutzungsbedingungen der API gelten zusätzlich zu den Bedingungen von RapidAPI.

Lizenzen

Die Prüfung nutzt die offiziellen Regelwerke und Open-Source-Bausteine unter ihren Lizenzen: die EN-16931-Artefakte des CEN und die XRechnung-Regeln der KoSIT (EUPL 1.2, Apache 2.0), die Factur-X-Regeln (Lizenz), SaxonJS (Copyright-Hinweis und Haftungsausschluss), xmllint-wasm, pdf-lib, fontkit, big.js und die DejaVu-Schriften.

Anbieter

Haag Automation, Julian Haag, Mühlstraße 35, 74360 Ilsfeld · julian@haag-automation.com · xmoo ist eine Marke von Haag Automation. Alle APIs