Billing guide

Dunnings

Dunning archive

The Dunning archive is a read-only view of already persisted local Dunning documents. It separates Mahnungsentwürfe from sent Mahnungen and exposes the source-shaped document metadata and line items needed for support and reconciliation.

The public Dunning API and archive reads remain read-only. A separate bounded local Admin workflow can create a zero-fee level-1 draft and immutable PDF for one narrowly proven outstanding native invoice, then place one frozen email in LocalQueueOnly. See dunning-workflow.md. It does not contact SMTP, a payment provider, a bank, Frisbii, or another production system and never sets SentAt.

Document areas

The list displays the document number, recipient, document and creation dates, total and currency, template, and sent/draft state. Detail pages additionally display sender and recipient addresses, tax identifiers, headline, prologue, epilogue, bearer medium, formatted address lines, and up to 500 invoice items.

When a historical row has no stored nullable Currency, the Admin view displays Währung unbekannt; it does not substitute the current merchant currency.

Every displayed value comes from the stored Dunning data. The reader does not mutate that data or reconstruct an older document from the current customer, contract, invoice, template, or settings. An incomplete historical row fails with a bounded compatibility error instead of showing invented content.

Filters and pagination

The API list endpoint is GET /api/v1/dunnings. Admin pages use the same bounded reader with a 50-row page size.

Input Behavior
drafts Strict optional boolean. true selects drafts, false selects sent rows, omission selects both.
customerId Exact same-merchant customer ID.
search At most 200 characters. Searches only Dunning number, recipient name/subname, customer ID, contract ID, external customer ID, and debitor account.
templateId Non-empty UTF-8 scalar, at most 200 bytes, without control characters; exact stored template match.
dateFrom / dateTo Exact YYYY-MM-DD, inclusive in the merchant timezone.
from Raw same-merchant 24-hex Dunning ID used as an exclusive tuple cursor.
skip Integer 0..1000, applied after the cursor; default 0.
take Integer 1..500; default 200.

Rows use the deterministic local order (CreationTime DESC, Id DESC). A cursor continues with older rows and excludes the anchor itself. Equal creation timestamps are ordered by descending ID. Newer rows committed during traversal appear only after starting a fresh traversal. Responses do not emit a Link or another continuation header.

The source OpenAPI describes the cursor’s purpose but not its exact boundary or behavior under concurrent inserts. This tuple rule is therefore documented as local behavior rather than Frisbii parity.

Bounds and validation

Top-level customer and contract IDs, plus every item invoice ID, must resolve to the expected kind inside the same merchant. Nullable absent IDs remain absent. A non-null missing, deleted, wrong-kind, or foreign reference returns 404 without exposing the other tenant.

API reads retain the existing sanitized started/completed audit events. Those events contain the operation identity and outcome, not recipient data, item values, DTO payloads, credentials, or document content. Reads create no financial, email, outbound, webhook, or Dunning mutation.

Current limitation

The local writer proves the complete remaining amount only for one native invoice with one exact Receivable and no allocation ambiguity. Payment allocation, partial payments, corrections, fees, higher levels, templates, automatic scheduling and every real delivery remain unimplemented. The public API exposes no Dunning mutation.