• v0.1.0 3c0eea5baf

    v0.1.0 Stable

    mxm released this 2026-09-02 19:32:38 +02:00 | 1 commits to main since this release

    Added

    • Delete operations for Invoice, Order, CreditNote, Voucher, Part, Tag
    • Full CheckAccount CRUD (get-check-account, create-check-account, update-check-account, delete-check-account)
    • Full Tag CRUD (get-tag, update-tag, delete-tag, list-tag-relations, remove-tag-relation)
    • Position-level CRUD (list/get/create/update/delete) for Invoice, Order, CreditNote, and Voucher line items
    • enshrine-invoice, enshrine-voucher — finalize/lock a document (irreversible)
    • upload-voucher-file — attach a receipt file to a voucher
    • create-recurring-invoice — recurring invoices (invoiceType WKR)
    • get-part-stock, get-next-customer-number
    • update-datev-export-config, get-export-job-status — split out of the DATEV export to match SevDesk's async job workflow
    • Tool count: 66 → 107

    Fixed

    • list-invoices advertised ISO date strings for start_date/end_date, but SevDesk requires Unix timestamps in seconds. The tool schema now exposes integer timestamps, preventing valid-looking date strings from silently returning empty results.
    • list-contacts returned empty names for organization contacts. formatContact only read surename/familyname, but SevDesk returns organization names in the name field. Now prefers name, falling back to surename + familyname for persons.
    • Client silently mishandled SevDesk's array-wrapped single-object responses. SevDesk wraps GET/POST/PUT responses for plain resource endpoints (Contact/{id}, Tag, CheckAccount, ...) as objects: [T], not objects: T. Tools that just JSON.stringifyd the raw result masked this; get-check-account's field-picking formatter silently produced {}. getSingle/post/put now unwrap a one-element array.
    • create-tag posted to the wrong endpoint (Tag/Factory/create, which 500s) instead of plain POST /Tag.
    • create-part didn't require part_number, even though SevDesk's API does — calls without it failed with an opaque 400.
    • create-invoice/create-order/create-credit-note were missing contactPerson (a SevUser reference), required since SevDesk 2.0 — caused a raw SQL NOT NULL violation.
    • taxRule (replaces taxType in SevDesk 2.0) was never sent on Invoice, Order, CreditNote, Voucher — added tax_rule_id param (default 1) alongside the existing taxType.
    • create-voucher used the deprecated accountingType for positions; SevDesk 2.0 requires accountDatev instead. Renamed accounting_type_id → account_datev_id, sourced from get-expense-accounts/get-revenue-accounts.
    • create-order was fully broken. Required, previously-missing fields: order_number (no auto-numbering endpoint exists for orders, unlike invoices), addressCountry, order-level taxRate, and version as an integer starting at 0 (was sent as the string '1').
    • create-credit-note was missing the genuinely-required deliveryDate. Documented (not "fixed", since it's a SevDesk-side limitation) that bookingCategory: ACCOUNTING_TYPE is rejected outright by the API, and the remaining categories require linking an origin document via refSrcInvoice/refSrcVoucher.
    • Factory endpoints (*/Factory/save*) return a nested wrapper ({objects: {invoice: {...}}}), one level deeper than the plain-resource unwrap handles. create-invoice/order/credit-note/voucher now destructure the nested key — previously produced garbage output like {"contact": null, "statusLabel": "Unknown (undefined)"} despite the document actually being created.
    • All export tools were non-functional. export-invoiceCsv/voucherListCsv/transactionsCsv require a nested sevQuery filter object, not flat startDate/endDate params (the flat params caused "Mapper Export was not found" — the API couldn't route the request). Invoice export additionally needs Unix timestamps, not date strings. Export/datevCSV is deprecated server-side in favor of an async job flow: update-datev-export-config (which itself needs undocumented accountantNumber/accountantClientNumber fields) → export-datev (starts the job — must be POST, not GET as the spec's method entry claims) → get-export-job-status (polls for the download URL).
    • export-datev's scope param was a made-up enum ("INVOICES"/"VOUCHERS"/"ALL"); the real API expects a string of up to 5 letters (E/X/T/C/D), e.g. "EXTCD". Also exposed exportByPaydate, includeEnshrined, enshrineDocuments, and includeDocumentImages — without the latter, the DATEV export ZIP only contained the Buchungsstapel CSV, not the Belegbilder (receipt/invoice document images) required for GoBD-compliant archiving.
    • creditDebit documentation on voucher tools was inverted. Docs claimed "C"=Credit/Revenue, "D"=Debit/Expense; per SevDesk's actual docs it's the opposite: C = you bought something (expense, Kreditorenbeleg), D = you sold something (revenue, Debitorenbeleg). The data flow itself was always correct — only the misleading description, which led a caller to create a voucher in the wrong direction.

    Verified live

    Every fix above was tested end-to-end against a real SevDesk account (create → get → update/delete → confirm), including a full DATEV export job run to a working signed download URL. Test data was cleaned up after each run.

    Downloads