Wie man eine konforme E-Rechnung mit n8n und SealDoc generiert
Eine konforme E-Rechnung zu erzeugen, umfasst mehr bewegliche Teile, als es zunächst aussieht. Sie benötigen eine gültige XML-Rechnung, das richtige EN 16931-Profil, einen PDF/A-3-Container, in den dieses XML eingebettet ist, und idealerweise einen RFC 3161-Zeitstempel, bevor alles in Ihr Archiv wandert. All das in eine eigene Integration einzubauen, bedeutet wochenlange Arbeit.
Dieses Tutorial setzt dasselbe Ergebnis in n8n mit dem Community-Node n8n-nodes-sealdoc zusammen. Kein eigener Code. Der Workflow erzeugt die Rechnung, holt das XML und das PDF/A-3 ab und speichert beides.
Voraussetzungen
- Eine selbst gehostete n8n-Instanz mit aktivierten Community-Nodes.
- Ein SealDoc-Workspace mit API-Zugang: der kostenlose Developer-Tarif oder ein beliebiger kostenpflichtiger Tarif. Siehe Preise.
- Einen SealDoc-API-Schlüssel. Legen Sie ihn in der SealDoc-App unter Integration → API Keys an. Kopieren Sie ihn sofort: Er wird nur einmal angezeigt.
- Ihre Unternehmensdaten. Der Verkäufer auf der Rechnung ist Ihr eigenes Unternehmen, und dessen USt-IdNr. muss mit der USt-IdNr. Ihres SealDoc-Workspace übereinstimmen.
Installieren Sie den Node in n8n unter Settings → Community nodes → Install mit dem Paketnamen n8n-nodes-sealdoc. Installieren Sie Nodes stattdessen von Hand, führen Sie Folgendes in Ihrem n8n-Nodes-Ordner aus (meist ~/.n8n/nodes) und starten Sie n8n danach neu:
npm i n8n-nodes-sealdoc
Legen Sie anschließend die Credential an: Credentials → New → SealDoc API, und fügen Sie Ihren Schlüssel in das Feld API Key ein. Lassen Sie Base URL auf https://api.sealdoc.eu stehen.
Was der Workflow macht
- Ein Trigger liefert die Rechnungsdaten als JSON: ein Webhook, eine Datenbankzeile, eine Formulareingabe oder eine beliebige andere n8n-Quelle.
- SealDoc · Invoice · Generate erstellt die E-Rechnung, validiert sie und versiegelt sie in einem PDF/A-3. Das geschieht innerhalb des Aufrufs: Der Node gibt einen fertigen Job zurück.
- SealDoc · Invoice · Get XML gibt das XML der E-Rechnung als Datei zurück.
- Ein HTTP Request-Node lädt das PDF/A-3 herunter.
- Ein Speicher-Node legt beide Dateien in Ihrem Archiv ab.
Schritt 1: Den Trigger einrichten
Erstellen Sie einen neuen Workflow und fügen Sie einen Webhook-Trigger mit der HTTP-Methode POST hinzu. So erhalten Sie eine URL, die jedes System mit Rechnungsdaten aufrufen kann. Zum Testen eignet sich ein Manual Trigger mit festen Daten genauso gut.
Ein minimales Beispiel dafür, was der Trigger liefern kann:
{
"invoiceNumber": "INV-2026-00042",
"invoiceDate": "2026-05-06",
"dueDate": "2026-06-05",
"buyer": {
"name": "Widget BV",
"vatNumber": "NL987654321B01",
"address": "Keizersgracht 10",
"postalCode": "1015 CN",
"city": "Amsterdam",
"country": "NL"
},
"line": {
"description": "Consulting services May 2026",
"quantity": 10,
"unitPriceExclVat": 150.00
}
}
Der Verkäufer steht nicht in diesem Payload. Er ist Ihr eigenes Unternehmen, also legen Sie ihn einmalig im Node fest.
Schritt 2: Invoice · Generate hinzufügen
Fügen Sie einen SealDoc-Node hinzu, benennen Sie ihn in Generate invoice um und stellen Sie Folgendes ein:
- Resource: Invoice. Operation: Generate.
- Invoice Number Source: Own Number. Invoice Number:
{{ $json.invoiceNumber }}. Soll SealDoc Ihre Rechnungen nummerieren? Wählen Sie dann stattdessen SealDoc Numbering Series. - Invoice Date:
{{ $json.invoiceDate }}. Due Date:{{ $json.dueDate }}. - Currency: EUR.
- VAT Rate:
0.21. Der Satz ist ein Anteil: 21 % sind also 0.21. Lassen Sie VAT Category auf “derive from the rate” und VAT Label leer: Bei einem Normalsatz schreibt SealDoc die Steuerbezeichnung selbst. - Seller: Ihr Unternehmen, mit Name, VAT Number, Address, Postal Code, City und Country (zweistelliger Code).
- Buyer Source: Buyer Details. Buyer: Ordnen Sie jedes Feld aus dem Trigger zu, zum Beispiel
{{ $json.buyer.name }}und{{ $json.buyer.postalCode }}. Kunden, die Sie in SealDoc gespeichert haben, verwenden Sie mit Buyer Profile direkt. - Lines: Fügen Sie eine Position hinzu, mit Description
{{ $json.line.description }}, Quantity{{ $json.line.quantity }}, Unit Hour und Unit Price (Excl. VAT){{ $json.line.unitPriceExclVat }}. - Profile: Basic (Factur-X 1.0). Der Node bietet außerdem XRechnung DE, das eine Buyer Reference (die Leitweg-ID) und einen Verkäuferkontakt benötigt, sowie Peppol BIS 3.0 (UBL 2.1), das die Peppol-Endpoint-IDs beider Parteien benötigt.
- RFC 3161 Timestamp: an, das ist die Standardeinstellung.
Wählen Sie Ihre SealDoc-API-Credential aus und führen Sie den Node aus. Die Antwort sieht so aus:
{
"jobId": "3f6c2a9e-8d41-4b7a-9c0e-5a2b1d7e4f10",
"status": "completed",
"statusUrl": "/api/jobs/3f6c2a9e-8d41-4b7a-9c0e-5a2b1d7e4f10"
}
completed bedeutet: Die Rechnung ist erstellt, gegen EN 16931 validiert und versiegelt. Polling ist nicht nötig. Meldet eine Antwort doch einmal queued oder processing, sagt Ihnen ein SealDoc · Job · Get-Node mit derselben jobId, wann sie fertig ist.
Schritt 3: Das XML abrufen
Fügen Sie einen zweiten SealDoc-Node hinzu: Resource Invoice, Operation Get XML, Job ID {{ $('Generate invoice').item.json.jobId }}. Der Node gibt das XML der E-Rechnung als Binärdatei im Feld data zurück: factur-x.xml für das Basic-Profil, xrechnung.xml für XRechnung und peppol-ubl.xml für Peppol BIS.
Schritt 4: Das PDF/A-3 herunterladen
Fügen Sie einen HTTP Request-Node hinzu:
- Method: GET
- URL:
https://api.sealdoc.eu/api/download/{{ $('Generate invoice').item.json.jobId }} - Authentication: Generic Credential Type, dann Header Auth, mit dem Namen
X-Api-Keyund Ihrem API-Schlüssel als Wert. - Response Format: File.
Das Ergebnis ist das versiegelte PDF/A-3 mit eingebettetem XML.
Schritt 5: Das Ergebnis speichern
Fügen Sie den Speicher-Node hinzu, der zu Ihrem Stack passt: Google Drive, Dropbox, einen S3-kompatiblen Bucket, SFTP auf Ihren eigenen Server oder Write Binary File direkt auf dem n8n-Host.
Ab dem Starter-Tarif hat jeder Job außerdem ein Legal Evidence Pack: GET /api/jobs/{id}/evidence-pack, mit demselben X-Api-Key-Header. SealDoc stellt es direkt nach dem Job zusammen; fragen Sie in den ersten Augenblicken danach, antwortet die API mit 409 und einem Retry-After-Header. Ein kurzer Wait-Node vor der Anfrage genügt also.
Wenn etwas schiefgeht
Fehler kommen sofort zurück, als Antwort mit einem code:
- 400 bei ungültiger Eingabe, zum Beispiel
seller_required,currency_requiredoderinvalid_vat_rate. - 402
plan_feature_required, wenn Ihr Tarif die Funktion nicht enthält. - 403
seller_vat_mismatch, wenn die USt-IdNr. des Verkäufers von der Ihres Workspace abweicht. - 409
quota_reached, wenn Ihr monatliches Kontingent aufgebraucht ist. - 422
einvoice_invalid, wenn die Rechnung die Validierung nicht besteht.
Standardmäßig stoppt der SealDoc-Node den Workflow bei einem Fehler. Stellen Sie die Einstellung On Error des Nodes so ein, dass er mit einem Fehlerausgang weiterläuft, und leiten Sie diesen Ausgang an Slack oder per E-Mail weiter, damit ein Mensch sieht, was korrigiert werden muss.
Was Sie erhalten
Ein PDF/A-3, das jeder PDF-Betrachter als lesbare Rechnung öffnet, mit eingebettetem XML für Buchhaltungssoftware, die Factur-X oder ZUGFeRD importiert. Das RFC 3161-Zeitstempel-Token wird mit dem Job gespeichert und lässt sich separat herunterladen (GET /api/jobs/{id}/timestamp). Ziehen Sie das PDF in unseren kostenlosen Validator, um das Prüfergebnis und jeden einzelnen Befund selbst zu sehen.
Nächste Schritte
- Vorhandene Rechnungen validieren: SealDoc · Validator · Check validiert eine Factur-X- oder ZUGFeRD-Datei, die Sie bereits haben, ohne etwas zu erzeugen.
- Andere Dokumente rendern: SealDoc · Document · Generate macht aus Markdown oder HTML in einem einzigen Aufruf ein versiegeltes PDF/A-3.
- Ausgestellte Rechnungen auslesen: SealDoc · Invoice · Get Summary liefert Rechnungsnummer, Profil, Sprache und USt-Summen einer erzeugten Rechnung.
Die vollständige API-Referenz mit OpenAPI-Spezifikation und curl-Beispielen ist auf unserer Entwicklerseite verlinkt.