Lexware Office API — Quirks + Voucher-Body-Felder

Wissen aus VP1 (av-beleg-pipeline). Wiederverwendbar fuer alle MCP-Builds + Routinen die Lexware-API schreiben.

API-Basics

  • Base-URL: https://api.lexware.io
  • Auth: Bearer-Token im Authorization-Header. JWT-shaped Personal-API-Key, generiert unter app.lexware.de → Persoenliche Einstellungen → Oeffentliche API. Kein OAuth.
  • Docs: developers.lexware.io/docs/ (Hauptdoku, redirected von alter developers.lexoffice.io-Domain)
  • Content-Type: application/json durchgaengig
  • Encoding: UTF-8

Voucher-Endpoint (POST /v1/vouchers)

Voucher-Top-Level-Felder

Bestaetigt durch Doku-Recherche VP1 (2026-05-20):

FeldTypePflichtNotiz
typestring enumjasalesinvoice / salescreditnote / purchaseinvoice / purchasecreditnote
voucherNumberstringneinEigene Nummer, sonst leer
voucherDatestring ISO-8601jaBeleg-Datum
totalGrossAmountfloatjaBrutto-Gesamt
totalTaxAmountfloatjaUSt-Gesamt
taxTypestring enumjanet oder gross
useCollectiveContactbooljatrue wenn contactId=null (Lexware-eigene Sammelkontakt-Logik)
contactIdstringneinUUID des Lexware-Kontakts
voucherItemsarrayjaItem-Liste, siehe unten
currencystringneinDefault EUR
remarkstringneinFreier Text-Note („closing text note”). Genutzt fuer GoBD-konforme Beschreibungen — Bewirtungsbeleg-Anlass, Teilnehmer, Anlass. Mensch-lesbar im Lexware-UI fuer StB. Bestaetigt vorhanden via Synesty-Connector-Doku + Credit-Notes-Analogie.

voucherItems-Item-Felder

FeldTypePflichtNotiz
amountfloatjaBrutto-Betrag des Items
taxAmountfloatjaUSt-Anteil
taxRatePercentintjaUSt-Satz (z.B. 19 oder 7)
categoryIdstringjaBuchungskategorie-ID (siehe list_posting_categories)
descriptionstringoptionalWahrscheinlich-vorhanden (Standard-Pattern aus Lexware lineItems in Invoices/CreditNotes). Live-Test mit Erst-Use noetig — Lexware-API ist Schema-tolerant, unbekannte Felder werden silently ignored statt 400-rejected.

Architektur-Empfehlung fuer GoBD-Beschreibung

remark auf Voucher-Top-Level ist der primaere GoBD-Beschreibungs-Anker (sicher persistiert). voucherItems[].description ist optional als Item-Detail-Kontext fuer Multi-Line-Belege (Amazon-Bestellung mit USB-Kabel + Buch, Restaurant-Rechnung mit Speisen + Getraenken).

Beispiel Bewirtungsbeleg:

create_voucher(
    voucher_type="purchaseinvoice",
    voucher_date="2026-05-20",
    contact_id=None,
    line_items=[
        {
            "amount": 47.0,
            "taxAmount": 3.08,
            "taxRatePercent": 7,
            "categoryId": "bewirtung-kategorie-id",
            "description": "Speisen + Getraenke Restaurant Da Marco, Hamm",
        }
    ],
    remark=(
        "Bewirtungsbeleg. Geschaeftliches Gespraech mit Andre Vidic "
        "(Vibe Factory). Hamm, 2026-05-20. "
        "Anlass: MCP-Hosting-Pilot Welle 2 Steuerung."
    ),
)

Weitere Quirks

Idempotency-Header

Idempotency-Key-Header mit UUID4 pro POST/PUT empfohlen. Verhindert Duplikate bei Netzwerk-Retry. Lexware merkt sich den Key 7 Tage. mcp-lexware setzt das automatisch in _idempotency_headers().

Optimistic-Lock bei Updates

Bei PUT /v1/contacts/{id} und aehnlichen Update-Endpoints ist ein version-Feld im Body Pflicht. Workflow: erst GET, dann den version-Wert zurueckschreiben. Lexware rejected mit 409 wenn version stale ist. Read-Modify-Write-Pattern.

Voucher- vs Invoice-Endpoints

Unterschiedliche Endpoints fuer aehnliche Konzepte:

EndpointWas
/v1/voucherlistListe aller Vouchers (kombiniert sales+purchase)
/v1/vouchers/{id}Detail eines Vouchers
/v1/vouchersPOST: neuer Voucher
/v1/invoicesnur Sales-Invoices (Rechnungen)
/v1/invoices/{id}Detail einer Rechnung

Voucher ist die generische Beleg-Form (eingehende Lieferanten-Rechnung, Sales-Receipt), Invoice ist nur Ausgangsrechnung mit Rechnungsnummer-Logik.

Finalize via Query-Param

PUT /v1/invoices/{id}?finalize=true macht aus Invoice-Draft eine finale Rechnung mit Nummer. Kein separater Finalize-Endpoint.

DATEV-Export asynchron

/v1/export/datev?from=YYYY-MM-DD&to=YYYY-MM-DD ist async Job-API. Response kann eine Download-URL enthalten statt CSV direkt. Polling auf Job-Status moeglicherweise noetig.

Schema-Toleranz

Lexware-API ist tendenziell schema-flexibel — unbekannte Felder im Request-Body werden meist silently ignored (kein 400). Das ist hilfreich (forward-compat) und gefaehrlich (Tippfehler werden silently durchgelassen). Best Practice: nach jedem schema-relevanten Patch ein Read-back (get_voucher) machen und pruefen welche Felder zurueckkommen.

Live-Test-TODO (offen nach VP1)

voucherItems[].description ist optimistic gepatcht (Code in mcp-lexware Z.397) aber nicht live-verifiziert. Beim ersten echten Welle-1-Beleg pruefen: kommt description in get_voucher-Response zurueck? Falls nein → GoBD-Beschreibung lebt nur in remark (kein Verlust, nur Item-Detail-Granularitaet weg).

Quellen

  • developers.lexware.io/docs/ — offizielle Doku (Credit-Notes-Section bestaetigt remark + description-Pattern, Voucher-Section in WebFetch-Window abgeschnitten)
  • Synesty-Connector-Doku — bestaetigt remark als Voucher-Top-Level-Field
  • VP1-Patch im Code: ~/source/mcps/mcp-lexware/src/mcp_lexware/server.py Z.371-414 (create_voucher-Signatur mit remark)
  • VP1-Tests: ~/source/mcps/mcp-lexware/tests/test_create_voucher.py (4 Scenarios)