API · v1 · stabil
CODEMETA OS Developer Center
Konsole öffnen
Module

Billing

Das Billing-Modul deckt den Sales-to-Cash- und Procurement-Flow ab: Rechnungen, Bestellungen sowie die zugrunde liegenden Produktstammdaten. Positionen, Zahlungen, Korrekturen und Versand-Logs liegen direkt am jeweiligen Beleg-Datensatz als typisierte Felder — kein eigenes Sub-Resource- Schema, keine separaten CRUD-Endpoints.

Resources

ResourcePfadPermission-PräfixSequenz
Rechnungen/api/v1/invoicesinvoiceINV-
Bestellungen/api/v1/purchase_orderspurchase_orderPO-
Produkte/api/v1/productsproduct
Produkt-Kategorien/api/v1/product_categoriesproduct_category

Schemas

Invoice

invoices4 Permissions

Schema for validating Rechnung (invoice) entities

partyId uuid erforderlich

Customer party UUID

invoiceNumber string optional

Auto-generated sequence number (e.g. RE-2026-00001)

max 1000 Zeichenread-onlynullable
invoiceDate date optional

Invoice date

nullable
dueDate date optional

Payment due date

nullable
status string erforderlich

Invoice lifecycle status. POSTED = verbucht / revisionssicher festgeschrieben (lockedAt set). SENT = an Kunden versandt. Beide sind immutable.

DRAFTPOSTEDSENTPAIDPARTIALLY_PAIDOVERDUECANCELLEDCREDITED
Default: "DRAFT"
salesInvoiceType string optional

Type of sales invoice (mirrors weclapp salesInvoiceOrigin). ADVANCE_PAYMENT=Anzahlung, PART_PAYMENT=Teilrechnung, FINAL=Schlussrechnung, RECURRING=wiederkehrend

STANDARDADVANCE_PAYMENTPART_PAYMENTPREPAYMENTFINALRECURRINGRETAIL
Default: "STANDARD"
bookingDate date optional

Buchungsdatum für DATEV (may differ from invoiceDate). Set on POSTED, drives the booking period.

nullable
lockedAt datetime optional

When the invoice was locked (POSTED). After this the invoice is immutable except for status changes (PAID/OVERDUE/CANCELLED) and dunning fields.

read-onlynullable
lockedBy uuid optional

User UUID who posted (locked) the invoice

read-onlynullable
contentHash string optional

SHA-256 hash of canonical invoice content at lock time (GoBD revisionssicher). Verified on every read after POSTED.

max 128 Zeichenread-onlynullable
recordAddressSnapshot object optional

Frozen invoice (recipient) address snapshot taken at POSTED. GoBD requires the address as printed on the original document.

read-onlynullable
name string optional
max 300 Zeichennullable
addressLine1 string optional
max 300 Zeichennullable
addressLine2 string optional
max 300 Zeichennullable
postalCode string optional
max 20 Zeichennullable
city string optional
max 200 Zeichennullable
state string optional
max 200 Zeichennullable
countryCode string optional
max 2 Zeichennullable
vatRegistrationNumber string optional
max 50 Zeichennullable
deliveryAddressSnapshot object optional

Frozen delivery address snapshot (if different from invoice address)

read-onlynullable
name string optional
max 300 Zeichennullable
addressLine1 string optional
max 300 Zeichennullable
addressLine2 string optional
max 300 Zeichennullable
postalCode string optional
max 20 Zeichennullable
city string optional
max 200 Zeichennullable
state string optional
max 200 Zeichennullable
countryCode string optional
max 2 Zeichennullable
exchangeRate string optional

Exchange rate to EUR at invoice date. Only set when currency != EUR. Used for DATEV export.

Patternnullable
source string optional

How the invoice was created

MANUALPERFORMANCE_RECORDSALES_ORDERCONTRACTWECLAPPCREDIT_NOTEWHOLESALE_LICENSING
Default: "MANUAL"
customerTenantId string optional

Customer tenant this invoice was generated for (only set when source=WHOLESALE_LICENSING).

PatternDefault: nullnullable
invoiceType string optional
INVOICECREDIT_NOTE
Default: "INVOICE"
creditedInvoiceId string optional

Original invoice ID (for credit notes)

PatternDefault: nullnullable
contractId string optional

Source contract (if generated from recurring billing)

PatternDefault: nullnullable
dunningLevel integer optional
0 – 3Default: 0
lastDunningAt datetime optional
Default: nullnullable
dunningBlockedUntil date optional

Dunning suspended until this date

Default: nullnullable
performanceRecordId uuid optional

Source performance record UUID (if generated from Leistungsnachweis)

nullable
title string optional

Invoice title / subject

max 200 Zeichennullable
introText string optional

Introductory text above positions

max 2000 Zeichennullable
closingText string optional

Closing text below positions

max 2000 Zeichennullable
notes string optional

Internal notes (not printed)

max 2000 Zeichennullable
openTicketNotes object[] optional

ADR 0146 — Snapshot copied from the source Leistungsnachweis: tickets that were still open at billing time but were unlocked via `ticket.billingOverride`. The invoice PDF renders a neutral "Hinweise"-section listing the affected ticket numbers; the internal reason is intentionally NOT propagated here.

Default: []nullable
ticketId uuid erforderlich
ticketNumber string erforderlich
max 50 Zeichen
title string optional
max 500 Zeichennullable
items object[] optional

Invoice line items

Default: []
position integer optional
≥ 1
description string erforderlich
max 500 Zeichen
unit string optional
max 20 Zeichennullable
quantity number erforderlich
≥ 0
unitPrice string erforderlich

Decimal string, e.g. "125.00"

vatRate string optional

VAT rate as percent string

Default: "19"
netAmount string optional

Computed: quantity * unitPrice

nullable
articleId string optional

Article reference (local UUID or weclapp article id)

max 64 Zeichennullable
articleNumber string optional

Article SKU / weclapp articleNumber

nullable
itemType string optional

Categorizes the line item origin

SERVICETRAVEL_DISTANCETRAVEL_TIMETRAVEL_OTHERFLAT_RATETICKETMATERIAL
nullable
materialBucketId uuid optional

Source material bucket UUID (if generated from Materialkorb)

nullable
contractId string optional
Default: nullnullable
contractItemId string optional

Which contract position generated this invoice line

Default: nullnullable
timeRecordId string optional

Source time_record UUID — set when this line was generated from a single booking (perEntry, ungrouped perTicket, or travel linked via trip.timeRecordId).

PatternDefault: nullnullable
timeRecordNumber string optional

Human-readable record number (e.g. TR-2026-00042) of the source time record. Snapshotted at build time so the UI can deep-link without an extra fetch.

max 50 ZeichenDefault: nullnullable
ticketId string optional

Source ticket UUID — set when this line aggregates time records of one ticket (perTicket) or originates from a TR with referenceType=TICKET.

PatternDefault: nullnullable
accountCode string optional

DATEV revenue account (Erlöskonto, e.g. "8400"). Falls back to article.revenueAccountCode at posting time.

max 20 ZeichenDefault: nullnullable
costCenterId string optional

Cost center UUID (Kostenstelle) for DATEV

PatternDefault: nullnullable
costTypeId string optional

Cost type UUID (Kostenträger) for DATEV

PatternDefault: nullnullable
taxKey string optional

DATEV Steuerschlüssel (e.g. "9" for 19% USt., "8" for 7%)

max 10 ZeichenDefault: nullnullable
netAmount string optional

Net total (excl. VAT) as decimal string

Patternnullable
vatAmount string optional

VAT total as decimal string

Patternnullable
grossAmount string optional

Gross total (incl. VAT) as decimal string

Patternnullable
vatRate string optional

Default VAT rate for this invoice

Default: "19"
currency string optional
max 3 ZeichenDefault: "EUR"
paymentTermsDays integer optional

Payment terms in days (e.g. 14, 30)

≥ 0nullable
pdfFileId uuid optional

Reference to stored PDF file in files collection

nullable
weclappId string optional

External weclapp sales invoice ID (if synced from weclapp)

read-onlynullable
weclappBaseUrl string optional

Base URL of the weclapp tenant (e.g. https://demo.weclapp.com) for deep-linking

read-onlynullable
externalVersion string optional

External system version (e.g. weclapp `version` field). Used to detect changes without re-downloading the PDF.

read-onlynullable
syncedAt datetime optional

Timestamp of the last successful sync from the external system

read-onlynullable
customerPaymentReportedAt datetime optional

Set when the customer pressed "Bezahlt gemeldet" in the portal. Does NOT change `status` — the MSP confirms separately. UI surfaces this as a yellow "Zahlung gemeldet" pill until the MSP transitions to PAID.

read-onlynullable
customerPaymentReportedBy uuid optional

Customer portal user who reported the payment

read-onlynullable
customerPaymentReference string optional

Optional reference text from the customer (e.g. SEPA reference, IBAN-Last4)

max 200 Zeichenread-onlynullable
groupingMode string optional

Grouping mode used when generating line items from performance record

onePositionperTicketperEntry
nullable
servicePeriodFrom date optional

Service period start (from performance record)

nullable
servicePeriodTo date optional

Service period end (from performance record)

nullable
salesOrderId string optional

Source sales order UUID (if generated from order)

PatternDefault: nullnullable
proposalId string optional

Source proposal UUID (if traceable to a proposal)

PatternDefault: nullnullable

Custom-Endpoints

Über das generische CRUD hinaus gibt es spezialisierte Routen unter /api/v1/billing/.... Die exakten Bodies und die vollständige Liste sehen Sie in der OpenAPI-Spec.

Lifecycle

Rechnungen

draft → issued → (paid | overdue) → (closed | void)

draft lässt sich beliebig editieren. Ab issued sind Positionen schreib- geschützt; Korrekturen laufen über typisierte Korrektur-Felder am Datensatz oder über eine Storno-Rechnung.

Zahlungen

Zahlungseingänge werden als typisierte Liste am invoice-Datensatz gepflegt (siehe Schema oben). Übersteigt die Summe der Zahlungen den Rechnungsbetrag, antwortet die API mit 422.

Currency, Steuer

Beträge sind decimal (typischerweise zwei Nachkommastellen, je nach Currency mehr). currency ist ISO-4217. Steuersätze hängen an der Position, nicht am Dokument — eine Rechnung kann mehrere Steuersätze nebeneinander tragen (7 %, 19 %, reverse charge).

Verwandt

Suche