Buchhaltung5 Min. Lesezeit

Mandanten-Belege automatisch konvertieren: API-Lösung für Steuerberater

Wie Steuerkanzleien PDF-Belege ihrer Mandanten per API automatisch in DATEV-kompatible Formate und ZUGFeRD-Rechnungen konvertieren. Mit Praxisbeispiel und Implementierungsleitfaden.

VT

Vellonode Team

Redaktion

|

Die Belegflut in der Steuerkanzlei

Steuerberater kennen das Problem: Mandanten liefern Belege in allen erdenklichen Formaten. Manche schicken ordentliche PDF-Rechnungen per E-Mail, andere fotografieren Kassenzettel mit dem Handy, wieder andere reichen einen USB-Stick mit 200 eingescannten Seiten ein. Am Monatsende türmt sich ein Berg aus PDFs, der manuell gesichtet, kategorisiert und in DATEV übertragen werden muss.

Bei einer typischen Kanzlei mit 80–120 Mandanten und durchschnittlich 30–50 Belegen pro Mandant pro Monat summiert sich das auf mehrere tausend Einzelbelege. Pro Beleg rechnen erfahrene Buchhalter mit 2–4 Minuten für die manuelle Erfassung — das sind hunderte Stunden pro Monat.

Warum die bisherigen Lösungen nicht reichen

DATEV Unternehmen online bietet zwar eine Belegverarbeitung, aber die eingebaute OCR liefert bei uneinheitlichen Belegen durchwachsene Ergebnisse. Besonders problematisch sind eingescannte Belege mit schlechter Qualität, handschriftliche Ergänzungen und Rechnungen in ungewöhnlichen Layouts.

Mandanten-Apps wie DATEV Meine Belege setzen voraus, dass der Mandant mitmacht — und zwar konsequent. In der Praxis nutzen das 20–30% der Mandanten zuverlässig. Der Rest liefert weiter per E-Mail oder Papier.

Der API-basierte Ansatz: Belege rein, strukturierte Daten raus

Die Vellonode API nimmt ein PDF entgegen und liefert:

  • Strukturierte Rechnungsdaten als JSON (Rechnungsnummer, Datum, Beträge, Positionen, Steuersätze, Käufer/Verkäufer)
  • ZUGFeRD 2.4 XML (EN16931-validiert)
  • Validierungsergebnis (sofort sichtbar, ob alle Pflichtfelder vorhanden sind)

Diese Daten können direkt in den DATEV-Import-Workflow fließen — ohne manuelle Zwischenschritte.

Der Workflow für die Kanzlei

Mandant sendet Belege (E-Mail, Upload, Cloud)
         │
         ▼
   PDF-Belege sammeln
         │
         ▼
   API-Aufruf pro Beleg
   POST /api/v1/invoices/convert?organizationId=IHRE_ORG_ID
         │
         ▼
   JSON-Daten + ZUGFeRD-XML
         │
         ▼
   Automatische Zuordnung
   (Mandant → Konto → DATEV)
         │
         ▼
   DATEV-Import oder manuelle Prüfung

Implementierung: Batch-Verarbeitung mit Python

Das folgende Script verarbeitet einen Ordner voller PDF-Belege und erzeugt für jeden Beleg eine JSON-Datei mit den extrahierten Daten:

import os
import requests
import json
from pathlib import Path

# organizationId ist ein Pflichtparameter – abrufbar über GET /api/v1/organizations
API_URL = "https://vellonode.de/api/v1/invoices/convert?organizationId=IHRE_ORG_ID"
API_KEY = "vk_live_IhrKeyHier"

INPUT_DIR = Path("./mandant_belege")
OUTPUT_DIR = Path("./verarbeitet")


def process_directory(input_dir, output_dir):
    output_dir.mkdir(exist_ok=True)
    pdf_files = list(input_dir.glob("*.pdf"))
    print(f"{len(pdf_files)} PDFs gefunden")

    results = []

    for i, pdf_path in enumerate(pdf_files, 1):
        print(f"[{i}/{len(pdf_files)}] {pdf_path.name}...")

        with open(pdf_path, "rb") as f:
            response = requests.post(
                API_URL,
                headers={
                    "Authorization": f"Bearer {API_KEY}"
                },
                files={
                    "file": (
                        pdf_path.name,
                        f,
                        "application/pdf",
                    )
                },
                data={"format": "zugferd,json"},
            )

        if response.status_code == 200:
            result = response.json()
            data = result["data"]

            # JSON speichern
            json_path = output_dir / f"{pdf_path.stem}.json"
            with open(json_path, "w", encoding="utf-8") as jf:
                json.dump(result, jf,
                          ensure_ascii=False, indent=2)

            results.append({
                "datei": pdf_path.name,
                "rechnungsnr": data.get("invoiceNumber"),
                "lieferant": (data.get("seller") or {})
                             .get("name"),
                "betrag": (data.get("totals") or {})
                           .get("grossTotal"),
                "valid": result["validation"]["valid"],
            })

            print(f"  OK: {data.get('invoiceNumber')} - "
                  f"{data.get('totals', {}).get('grossTotal')} EUR")
        elif response.status_code == 429:
            print("  Rate-Limit - warte...")
            import time
            retry = int(
                response.headers.get("Retry-After", "10")
            )
            time.sleep(retry)
        else:
            print(f"  Fehler: {response.status_code}")
            results.append({
                "datei": pdf_path.name,
                "fehler": response.status_code,
            })

    # Übersicht als CSV
    csv_path = output_dir / "uebersicht.csv"
    with open(csv_path, "w", encoding="utf-8") as csvf:
        csvf.write(
            "Datei;Rechnungsnr;Lieferant;Betrag;Valid\n"
        )
        for r in results:
            if "fehler" in r:
                csvf.write(f"{r['datei']};;;;"
                           f"FEHLER {r['fehler']}\n")
            else:
                csvf.write(
                    f"{r['datei']};{r['rechnungsnr']};"
                    f"{r['lieferant']};{r['betrag']};"
                    f"{'Ja' if r['valid'] else 'Nein'}\n"
                )

    print(f"\nFertig. Übersicht: {csv_path}")


if __name__ == "__main__":
    process_directory(INPUT_DIR, OUTPUT_DIR)

Bei großen Belegmengen empfiehlt sich eine parallele Verarbeitung mit concurrent.futures.ThreadPoolExecutor. Das Rate-Limit der API liegt bei 30 Requests pro Minute — mit 3–5 parallelen Threads nutzen Sie das optimal aus, ohne das Limit zu überschreiten.

Praxisbeispiel: Kanzlei mit 95 Mandanten

Eine mittelständische Steuerkanzlei in Süddeutschland betreut 95 Mandanten, überwiegend Handwerksbetriebe und kleine Dienstleister. Das monatliche Belegvolumen liegt bei 2.500–3.000 Eingangsrechnungen.

Ausgangslage:

  • 2 Vollzeit-Buchhalterinnen nur für die Belegerfassung
  • Durchschnittlich 3 Minuten pro Beleg (Sichten, Erfassen, Kontieren)
  • Fehlerquote: 2–3% — auffallend bei der Umsatzsteuervoranmeldung

Nach der API-Integration:

  • Ein Python-Script verarbeitet die Belege über Nacht in Batches
  • Am Morgen liegt eine CSV-Übersicht mit allen extrahierten Daten vor
  • Die Buchhalterinnen prüfen nur noch Belege, bei denen die Validierung Fehler meldet (ca. 15–20%)
  • Die restlichen 80% werden direkt in DATEV importiert

Ergebnis nach 3 Monaten:

  • Zeitaufwand für Belegerfassung: von 120 auf 30 Stunden pro Monat
  • Fehlerquote: unter 0,5%
  • Eine Buchhalterin konnte auf wertschöpfendere Tätigkeiten umgeschichtet werden (Mandantenberatung, Jahresabschlüsse)

Von JSON zu DATEV: Die Brücke bauen

Die API liefert strukturiertes JSON. Für den DATEV-Import brauchen Sie DATEV-Buchungssätze. Die Zuordnung folgt einem einfachen Schema:

JSON-FeldDATEV-FeldLogik
data.totals.grossTotalUmsatzBruttobetrag
data.totals.vatAmountSteuerbetragUSt-Betrag
data.lines[].vatRateBU-Schlüssel19% → BU 9, 7% → BU 8
data.seller.nameBelegfeld 1Lieferantenname
data.invoiceNumberBelegfeld 2Rechnungsnummer
data.invoiceDateBelegdatumRechnungsdatum

Die Erlös-/Aufwandskonten (z.B. 3400 für Wareneingang 19% im SKR03) können Sie über eine Zuordnungstabelle pro Mandant oder über den Lieferantennamen automatisch vergeben.

Die Vellonode-App bietet auch einen direkten DATEV-Export (Schnittstelle online v060) mit automatischer Kontenzuordnung. Wenn Sie die Web-Oberfläche bevorzugen statt der API, können Sie Belege auch dort hochladen und den DATEV-Export per Klick herunterladen.

Mandanten einbinden: Der Beleg-Upload-Workflow

Die eleganteste Variante: Mandanten laden ihre Belege selbst hoch. Dafür gibt es mehrere Ansätze:

1. Gemeinsames E-Mail-Postfach: Der Mandant schickt Rechnungen an eine dedizierte Adresse (z.B. [email protected]). Ein automatisierter Workflow verarbeitet die Anhänge per API.

2. Cloud-Ordner: Ein geteilter Ordner (Nextcloud, Google Drive, Dropbox) wird überwacht. Neue PDFs werden automatisch verarbeitet.

3. Vellonode-Account pro Mandant: Jeder Mandant erhält einen eigenen Zugang. Die Kanzlei sieht alle Organisationen in der Support-Ansicht und kann Daten mandantenübergreifend exportieren.

Nächste Schritte

  1. Konto erstellen unter vellonode.de/auth/register
  2. API-Key generieren unter Einstellungen → API
  3. Testlauf mit 10 Belegen eines Mandanten
  4. Zuordnungstabelle für DATEV-Konten pro Mandant aufbauen
  5. Batch-Script für den Produktivbetrieb einrichten

Die API-Dokumentation finden Sie unter /api/v1/openapi.

Passende Lösungen

Weitere Artikel

Bleiben Sie informiert

Erhalten Sie die neuesten Artikel zu E-Rechnung, Buchhaltung und KI-Automatisierung direkt in Ihr Postfach.

Kein Spam, jederzeit abbestellbar. Datenschutzerklärung