Mahnwesen
Überfällige Rechnungen verfolgen, Mahnregeln festlegen und Zahlungserinnerungen versenden.
Overdue tracking, dunning policy, and payment reminders (Mahnwesen).
Operationen
-
GET/dunning/overdueList overdue invoices (cursor-paginated, derived) -
GET/dunning/policyGet the entity's Mahnstufen policy -
PUT/dunning/policyReplace the entity's reminder ladder (admin-gated) -
PATCH/dunning/policySet which record of sending a reminder requires -
PUT/dunning/policy/chargesSet the late-payment interest and fee configuration, and nothing else -
GET/invoices/{id}/remindersThe per-invoice reminder history / Mahnverlauf -
POST/invoices/{id}/remindersSend the next-due Mahnstufe for an invoice -
GET/invoices/{id}/reminders/previewPreview the next-due reminder (byte-faithful dry-run) -
GET/invoices/{id}/reminders/preview.pdfPreview the next-due Mahnung as a PDF (byte-faithful) -
GET/invoices/{id}/reminders/{reminderId}/artifact.pdfRead the frozen per-reminder Mahnung letter
List overdue invoices (cursor-paginated, derived)
GET /dunning/overdue
The derived overdue set: status='issued' AND payment_state IN ('open','partially_paid') AND COALESCE(due_date, issue_date+30) < CURRENT_DATE. A paid/overpaid/void/draft/scheduled invoice never appears (the payment_state filter is load-bearing — it excludes overpaid, unlike the inbound open-invoices read). Per row: the derived daysOverdue, openAmountMinor (= totalGross − amountPaid − the same-currency partial credit notes), the current Mahnstufe (highest reminder level snapshot), and the SERVER-COMPUTED nextAction descriptor (which level is next, whether it is sendable, and why not) — so web never derives the schedule. Mode-scoped; keyset over (effectiveDueDate, id) ASC. Mounted only where dunning is enabled` (else 404).
- Erforderlicher Scope
-
documents:read - Zugang
- API-Schlüssel oder angemeldete Sitzung
Parameter
| Parameter | In | Typ | Beschreibung |
|---|---|---|---|
cursor | Query | string | Opaque keyset cursor from a prior page's |
limit | Query | integer | Standard: 50 Bereich: ≥ 1, ≤ 100 |
Antworten
-
200A page of overdue invoices (all fields server-derived) + an opaque
nextCursor.application/jsonobject -
400The query string was refused. Three distinguishable facts share this status, and a client should branch on the
errorcode rather than on the status:unknown_query_parameter— the request named one or more query parameters this deployment does not define, andparameterslists their names. Nothing was filtered and nothing was written. This is a DEPLOY-ORDER signal: it is what a client released ahead of the API sees, and it replaces the older behaviour in which an unrecognised parameter was silently ignored and the request answered200 OKwith the UNFILTERED collection — indistinguishable, to the caller, from the filter having been applied.validation_error— a parameter this endpoint does define carried an unusable value (including a required one being absent or too short).issues[]names the parameter and what was wrong with it.invalid_cursor— on cursor-paginated endpoints, the pagination cursor is malformed. No response on this path ever echoes a submitted VALUE; only parameter names appear.application/jsonUnknownQueryParameterError | ValidationError -
403Caller lacks the
documents:readscope. -
404Dunning is not enabled — the surface is not mounted.
Get the entity's Mahnstufen policy
GET /dunning/policy
The resolved per-entity dunning policy: the stored row, else the SHIPPED DEFAULT (the 4-level Zahlungserinnerung → 1./2./3. Mahnung set) so the feature works out of the box. ENTITY-scoped (not mode-scoped — one policy, the same in live + test). The interest/fee fields are INACTIVE (OFF / null / 0). Any active member may read.
- Erforderlicher Scope
-
documents:read - Zugang
- API-Schlüssel oder angemeldete Sitzung
Antworten
-
200The resolved policy (
isDefault= true when no row is stored yet).application/jsonDunningPolicy -
403Caller lacks the
documents:readscope. -
404Dunning is not enabled — the surface is not mounted.
Replace the entity's reminder ladder (admin-gated)
PUT /dunning/policy
Replaces the entity's reminder ladder (ON CONFLICT (entity_id)). Admin-gated (requireRole('admin') — a readonly caller 403s). Validation: levels ordered by strictly-increasing sequence, unique level keys, dayOffset non-negative and strictly increasing by sequence, newDeadlineDays ≥ 1.
levels is the only property of this body and it is REQUIRED, so there is no omission question here at all: no other stored value can be reached from this operation. Late-payment interest and dunning fees are set with PUT /dunning/policy/charges; the send-evidence requirement with PATCH /dunning/policy. Supplying an interest or fee property here is REFUSED by name (dunning_charges_not_on_replace) and nothing is written — it is never silently dropped, because that would report a change that did not happen.
- Erforderlicher Scope
-
documents:write - Zugang
- API-Schlüssel oder angemeldete Sitzung
Request-Body erforderlich
application/json DunningPolicyInput
Antworten
-
200The stored policy.
application/jsonDunningPolicy -
400Validation error (ordering / uniqueness / bounds), or
dunning_charges_not_on_replace— the body carried an interest or fee property, which belongs toPUT /dunning/policy/charges. Nothing was written. -
403Caller lacks the admin role or the
documents:writescope. -
404Dunning is not enabled — the surface is not mounted.
Set which record of sending a reminder requires
PATCH /dunning/policy
Sets one setting and nothing else: which record of the invoice having gone out a reminder requires. Every other value on the policy is left exactly as it is — deliberately a separate operation from the whole policy replace, so saving reminder levels can never reset this rule without the caller intending it.
any — a dispatch you recorded yourself is enough. system_transmitted — only a dispatch this application performed counts.
Neither value permits a reminder for an invoice with no record of any kind. A reminder level, once sent, cannot be sent again.
- Erforderlicher Scope
-
documents:write - Zugang
- API-Schlüssel oder angemeldete Sitzung
Request-Body erforderlich
application/json object
Antworten
-
200The stored policy.
application/jsonDunningPolicy -
400Validation error.
-
403Caller lacks the admin role or the
documents:writescope. -
404Dunning is not enabled — the surface is not mounted.
Set the late-payment interest and fee configuration, and nothing else
PUT /dunning/policy/charges
Sets the entity's late-payment interest and dunning-fee configuration and nothing else. Every property is REQUIRED, so this body carries no omission question at all, and no other stored value can be reached from here — the reminder ladder and the send-evidence requirement are untouched. Unknown properties are refused.
Three properties are required-and-NULLABLE: null is a value you STATE (no rate is configured), and it is a different act from leaving the property out, which is refused.
The values are stored as passed and are NOT validated as active values; the shipped configuration is inactive (feature off, no rate, zero amounts) and this operation is the only way to move it. Admin-gated (requireRole('admin') — a readonly caller 403s). Creates the entity's policy row from the shipped default ladder if none exists yet, so the setting cannot silently fail to stick.
- Erforderlicher Scope
-
documents:write - Zugang
- API-Schlüssel oder angemeldete Sitzung
Request-Body erforderlich
application/json DunningPolicyCharges
Antworten
-
200The stored policy, with the new interest/fee configuration.
application/jsonDunningPolicy -
400Validation error — a property is missing, unknown, or out of bounds.
-
403Caller lacks the admin role or the
documents:writescope. -
404Dunning is not enabled — the surface is not mounted.
The per-invoice reminder history / Mahnverlauf
GET /invoices/{id}/reminders
The append-only reminder records for one invoice, oldest level first (ascending reminder level — reminders escalate contiguously). A PURE RLS-scoped read of the reminder facts; the invoice is NEVER mutated and the current Mahnstufe is not derived here (that is the highest reminder level on GET /dunning/overdue). METADATA-ONLY: the level, sent-at, channel, recipient, the facts stated (open amount, both deadlines) and the evidence — the rendered sent_subject/sent_body_html snapshot is retained on the row for evidence but deliberately NOT surfaced (GDPR, no over-exposure). A cross-scope or unknown invoice id, and an invoice with no reminders, both return an empty reminders array. Mounted only when dunning (else 404).
- Erforderlicher Scope
-
documents:read - Zugang
- API-Schlüssel oder angemeldete Sitzung
Parameter
| Parameter | In | Typ | Beschreibung |
|---|---|---|---|
id erforderlich | Pfad | string (uuid) | The invoice whose Mahnverlauf to read. |
Antworten
-
200The invoice's reminders, level-ordered (possibly empty).
application/jsonReminderHistory -
403Caller lacks the
documents:readscope. -
404Dunning is not enabled.
Send the next-due Mahnstufe for an invoice
POST /invoices/{id}/reminders
Sends the NEXT-DUE reminder level (the lowest the reminder level not yet sent whose dayOffset ≤ daysOverdue) in ONE transaction: it INSERTs the immutable immutable reminder record (snapshotting the level + the facts stated + the api-rendered subject/body) and INSERTs a an outbound-mail record of kind dunning the mail dispatcher sends. The invoice is NEVER mutated (a reminder references it; the 0058 guard holds). Exactly-once: the one record per invoice and level guard makes a duplicate same-level send roll back with no second email (→ 409 mahnstufe_already_sent). Honors the optional Idempotency-Key header (a client double-submit is a replay). Available only where dunning is enabled (else 404). The rendered subject/body are byte-identical to GET /invoices/{id}/reminders/preview for the same inputs (one shared render implementation — no drift).
- Erforderlicher Scope
-
documents:write - Zugang
- API-Schlüssel oder angemeldete Sitzung
Parameter
| Parameter | In | Typ | Beschreibung |
|---|---|---|---|
id erforderlich | Pfad | string (uuid) | The overdue invoice to remind. |
Idempotency-Key | Header | string | Optional client-supplied key that makes this mutating request safe to retry. The FIRST request runs and its outcome is recorded keyed by Länge: max. 255 |
Antworten
-
201The created reminder fact (or, on an Idempotency-Key replay, the recorded response).
application/jsonReminder -
403Caller lacks the
documents:writescope. -
404Invoice not in scope, or dunning is not enabled.
-
409correction_chain_indeterminate(one of this invoice's own cancellation documents has itself been cancelled, so the amount still owed cannot be determined automatically; returned ahead of every other reason, and NOTHING is written),cancelled_by_correction(an issued/paid384, or a381that reverses this invoice IN FULL, settles it by document and not by money; returned ahead ofnot_overdue, and NOTHING is written — a381covering only PART of the invoice reduces the open amount instead and leaves the invoice dunnable for the remainder),not_sent(the platform has no record of ever sending this invoice, so it may not be dunned; also returned ahead ofnot_overdue, since waiting never clears it — send the invoice viaPOST /invoices/{id}/sendfirst; NOTHING is written and the Mahnstufe stays free),not_overdue(paid/overpaid/void/draft/scheduled/not-yet-due),no_level_due(no level reached, or all reached levels sent),processing_restricted(DSGVO Art. 18), ormahnstufe_already_sent(the exactly-once dedup fired). AlsoIDEMPOTENCY_*on key conflicts. -
422no_recipient_email(no email on file — nothing written),email_settings_not_configured(no default SMTP config for this entity/mode — nothing written), orsandbox_recipient_not_allowed(test mode, sent by the platform's test sender: a recipient — including a copy or blind copy — is neither a confirmed reply address of the company nor the address of an active member of the account; the body names no address). Nothing is written and the Mahnstufe stays free. -
429sandbox_mail_daily_cap_reached— test mode, sent by the platform's test sender: this company has reached its daily limit of test-mode e-mails sent by the platform (counted per company over the Europe/Berlin calendar day: e-mails sent today plus e-mails still waiting to be sent). Nothing was written and nothing was sent; a reminder level stays free. The limit resets at midnight Europe/Berlin;Retry-Aftergives the seconds until then andlimitthe number. E-mails sent through the company's own mail server are not counted.-
Retry-AfterintegerSeconds until the next business day starts (Europe/Berlin midnight).
application/jsonobject -
Preview the next-due reminder (byte-faithful dry-run)
GET /invoices/{id}/reminders/preview
A READ-ONLY dry-run that renders the next-due level's subject + body for an invoice WITHOUT writing or sending anything (no reminder row, no outbox row). Byte-identical to what POST /invoices/{id}/reminders would persist for the same inputs — the same "single rendering implementation, no drift" principle as the PDF preview. Blocked states (cancelled_by_correction / not_sent / not_overdue / no_level_due / no_recipient / processing_restricted) surface as a calm blockedReason (a 200 body with null subject/body), never a hard error. Available only where dunning is enabled (else 404).
- Erforderlicher Scope
-
documents:read - Zugang
- API-Schlüssel oder angemeldete Sitzung
Parameter
| Parameter | In | Typ | Beschreibung |
|---|---|---|---|
id erforderlich | Pfad | string (uuid) | The invoice to preview a reminder for. |
Antworten
-
200The byte-faithful rendered reminder, or a calm blocked state.
application/jsonReminderPreview -
403Caller lacks the
documents:readscope. -
404Invoice not in scope, or dunning is not enabled.
Preview the next-due Mahnung as a PDF (byte-faithful)
GET /invoices/{id}/reminders/preview.pdf
A READ-ONLY render of the next-due Mahnstufe as a plain-letter Mahnung PDF (DIN 5008), streamed WITHOUT writing or sending anything (no reminder row, no outbox row, no object stored). Rendered via the SAME render-dunning client + copy/cost resolvers a send freezes, so the preview is byte-faithful to the artifact a send would persist. Unwatermarked. Mounted only when dunning AND dunning PDFs are enabled (else 404). A blocked state (not overdue / no level due / restricted) is a mapped 4xx; a renderer failure is 502.
- Erforderlicher Scope
-
documents:read - Zugang
- API-Schlüssel oder angemeldete Sitzung
Parameter
| Parameter | In | Typ | Beschreibung |
|---|---|---|---|
id erforderlich | Pfad | string (uuid) | The invoice to preview the next-due Mahnung for. |
Antworten
-
200The rendered Mahnung PDF (inline).
application/pdfstring (binary) -
403Caller lacks the
documents:readscope. -
404Invoice not in scope, or dunning / dunning PDFs are not enabled.
-
409correction_chain_indeterminate/cancelled_by_correction/not_sent/not_overdue/no_level_due/processing_restricted— nothing to preview. -
502render_failed— the Mahnung renderer is unavailable/errored.
Read the frozen per-reminder Mahnung letter
GET /invoices/{id}/reminders/{reminderId}/artifact.pdf
The CUSTOMER-FACING read of the FROZEN Mahnung PDF that was actually sent for a specific reminder (Mahnstufe) — not a re-render of the next-due preview. Requires documents:read; the {id} invoice is the authorization anchor: the {reminderId} must belong to that invoice under the caller's RLS scope. Streamed inline for the in-app Mahnverlauf viewer. Mounted only when dunning AND dunning PDFs are enabled (else 404). A reminder id belonging to another invoice/tenant, or a legacy email-only reminder with no frozen artifact, is a 404 (never leaks existence; the web shows no "Brief ansehen" affordance for such a row).
- Erforderlicher Scope
-
documents:read - Zugang
- API-Schlüssel oder angemeldete Sitzung
Parameter
| Parameter | In | Typ | Beschreibung |
|---|---|---|---|
id erforderlich | Pfad | string (uuid) | The invoice the reminder belongs to (the authorization anchor). |
reminderId erforderlich | Pfad | string (uuid) | The specific reminder (Mahnstufe) whose frozen letter to read. |
Antworten
-
200The frozen Mahnung PDF for that reminder (inline).
application/pdfstring (binary) -
403Caller lacks the
documents:readscope. -
404The reminder is unknown, does not belong to
{id}, is not in the caller's scope, has no frozen artifact (email-only), or dunning or dunning PDFs are not enabled.
Datenmodelle
Jedes Datenmodell dieser Gruppe einmal, mit allen Feldern – auch den verschachtelten. Verschachtelte Objekte sind aufklappbar; ein benannter Typ verweist auf seinen eigenen Abschnitt.
OverdueInvoice object
One row of the overdue read — every field is server-derived (no client computation).
| Feld | Typ | Beschreibung |
|---|---|---|
invoiceId erforderlich | string (uuid) | |
invoiceNumber erforderlich | string | null | |
customerId erforderlich | string (uuid) | null | |
buyerName erforderlich | string | |
currency erforderlich | string | |
effectiveDueDate erforderlich | string (date) | COALESCE(due_date, issue_date + 30). |
daysOverdue erforderlich | integer | CURRENT_DATE − effectiveDueDate (whole days). |
openAmountMinor erforderlich | integer | What is still owed, in minor units: totalGross − amountPaid − the same-currency partial credit notes. |
totalGrossMinor erforderlich | integer | The invoice gross in minor units (for the partial "von {gross}" sub-line). |
currentLevelLabel erforderlich | string | null | The derived current Mahnstufe label (highest reminder level snapshot), or null. |
currentLevelSentAt erforderlich | string (date-time) | null | When the current level was sent, or null. |
nextAction erforderlich | DunningNextAction |
Verwendet von:
GET /dunning/overdue
UnknownQueryParameterError object
The request named query parameters this endpoint does not define. A list endpoint refuses them rather than ignoring them, so a caller can never mistake an UNFILTERED collection for a filtered one.
| Feld | Typ | Beschreibung |
|---|---|---|
error erforderlich | string | Werte: "unknown_query_parameter" |
parameters erforderlich | Array<string> | The unrecognised parameter NAMES, deduplicated and sorted. Bounded at ten entries, and a name longer than 64 characters is omitted — a parameter name is caller-supplied text, and this response never reflects unbounded caller input. The array may therefore be EMPTY while the refusal still stands: the refusal is decided by the request, not by the length of this list. |
message | string | |
requestId | string |
Verwendet von:
GET /dunning/overdue
ValidationError object
A refused request body. error is validation_error when the body was read and failed validation (each problem is listed in issues), or invalid_json when the body is not valid JSON at all (then issues is absent). An unparsable body is answered 400 invalid_json on every operation that takes a JSON body. The submitted body is never echoed.
| Feld | Typ | Beschreibung | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
error | string | |||||||||||||
issues | Array<object> | Felder
|
Verwendet von:
GET /dunning/overdue
DunningPolicy object
The resolved per-entity dunning policy. Every interest/fee field is INACTIVE by default (OFF / null / 0). isDefault = true when the shipped default was returned (no stored row yet).
| Feld | Typ | Beschreibung |
|---|---|---|
levels erforderlich | Array<DunningLevel> | |
interestFeatureEnabled erforderlich | boolean | Master toggle (OFF by default — nothing legally-loaded renders). |
basiszinssatzBp erforderlich | integer | null | §247 BGB Basiszinssatz in basis points; null → no interest (fail-quiet). |
interestSpreadB2bBp erforderlich | integer | null | |
interestSpreadB2cBp erforderlich | integer | null | |
interestDayCountBasis erforderlich | string | null | |
dunningFeeMinor erforderlich | integer | Mahngebühr in minor units (conservative default 0). |
verzugspauschaleB2bMinor erforderlich | integer | §288 Abs.5 Verzugspauschale (B2B) in minor units (conservative default 0). |
updatedAt | string (date-time) | Present when resolved from a stored row. |
isDefault erforderlich | boolean | true when the shipped default was returned (no stored row). |
Verwendet von:
GET /dunning/policy , PUT /dunning/policy , PATCH /dunning/policy , PUT /dunning/policy/charges
DunningPolicyInput object
PUT /dunning/policy body — the reminder ladder, on its own. levels must be ordered by strictly-increasing sequence, with unique keys, non-negative dayOffset strictly increasing by sequence, and newDeadlineDays ≥ 1.
It is the only property and it is REQUIRED, so this body has no optional property and therefore no omission rule. No other stored value can be written through it: late-payment interest and dunning fees are set with PUT /dunning/policy/charges, and the send-evidence requirement with PATCH /dunning/policy. Sending an interest or fee property here is refused (dunning_charges_not_on_replace) and nothing is written.
| Feld | Typ | Beschreibung |
|---|---|---|
levels erforderlich | Array<DunningLevel> | Elemente: min. 1 |
Verwendet von:
PUT /dunning/policy
DunningPolicyCharges object
The late-payment interest and dunning-fee configuration, on its own. Every property is required — this body has no optional property and therefore no omission rule — and no other stored value can be written through it. Three properties are nullable: null means no value is configured and is something you STATE, which is not the same as leaving the property out (that is refused).
| Feld | Typ | Beschreibung |
|---|---|---|
interestFeatureEnabled erforderlich | boolean | Master switch for stating late-payment interest and fees on a reminder. While it is false, nothing is stated and no amount is charged, whatever the other properties hold. |
basiszinssatzBp erforderlich | integer | null | The § 247 BGB base rate in basis points, or null when none is configured. Null suppresses interest entirely — no rate is ever guessed. |
interestSpreadB2bBp erforderlich | integer | null | The § 288 Abs. 2 spread over the base rate for business debtors, in basis points, or null when none is configured. |
interestSpreadB2cBp erforderlich | integer | null | The § 288 Abs. 1 spread over the base rate for consumer debtors, in basis points, or null when none is configured. |
interestDayCountBasis erforderlich | string | null | How days are counted when interest is derived (for example Länge: max. 32 |
dunningFeeMinor erforderlich | integer | The Mahngebühr in minor units. A money amount — it is stored exactly as stated and is suppressed together with interest while the master switch is off. Bereich: ≥ 0 |
verzugspauschaleB2bMinor erforderlich | integer | The § 288 Abs. 5 late-payment lump sum for business debtors, in minor units. A money amount, stored exactly as stated. Bereich: ≥ 0 |
Verwendet von:
PUT /dunning/policy/charges
ReminderHistory object
The per-invoice Mahnverlauf: the invoice's reminders, level-ordered.
| Feld | Typ | Beschreibung |
|---|---|---|
invoiceId erforderlich | string (uuid) | |
reminders erforderlich | Array<ReminderHistoryItem> |
Verwendet von:
GET /invoices/{id}/reminders
Reminder object
One sent reminder — the immutable immutable reminder record, snapshotting the level + facts stated + the api-rendered content. subject / bodyHtml are byte-identical to the T02b preview for the same inputs.
| Feld | Typ | Beschreibung |
|---|---|---|
id erforderlich | string (uuid) | |
invoiceId erforderlich | string (uuid) | |
levelSequence erforderlich | integer | 0 = Zahlungserinnerung, 1 = 1. Mahnung, … |
levelKey erforderlich | string | |
levelLabel erforderlich | string | |
invoiceNumber erforderlich | string | null | |
effectiveDueDate erforderlich | string (date) | COALESCE(due_date, issue_date + 30). |
daysOverdue erforderlich | integer | |
openAmountMinor erforderlich | integer | The open amount the reminder states, in minor units: totalGross − amountPaid − the same-currency partial credit notes, as derived when it is sent. |
currency erforderlich | string | |
newPaymentDeadline erforderlich | string (date) | The new deadline this reminder sets (send date + newDeadlineDays). |
channel erforderlich | string | Werte: "email" |
toEmail erforderlich | string | Recipient at send time (never logged). |
subject erforderlich | string | |
bodyHtml erforderlich | string | |
interestChargedMinor erforderlich | integer | Interest/fee evidence — 0 unless interest and fees are switched on. |
feeChargedMinor erforderlich | integer | Interest/fee evidence — 0 unless interest and fees are switched on. |
createdAt erforderlich | string (date-time) |
Verwendet von:
POST /invoices/{id}/reminders
ReminderPreview object
The byte-faithful reminder dry-run. subject/bodyHtml are byte-identical to what a send persists for the same inputs, or null when blockedReason is set (a calm blocked state, not an error).
| Feld | Typ | Beschreibung |
|---|---|---|
levelKey erforderlich | string | null | |
levelLabel erforderlich | string | null | |
recipientEmail erforderlich | string | null | |
openAmountMinor erforderlich | integer | The open amount the reminder would state if sent now, in minor units: totalGross − amountPaid − the same-currency partial credit notes. |
currency erforderlich | string | |
originalDueDate erforderlich | string (date) | COALESCE(due_date, issue_date + 30). |
newDeadline erforderlich | string (date) | null | The new deadline the send would set, or null when blocked. |
daysOverdue erforderlich | integer | |
subject erforderlich | string | null | The api-rendered subject, or null when blocked. |
bodyHtml erforderlich | string | null | |
blockedReason erforderlich | string | null | Why there is nothing to send now, or null when a reminder is sendable. Werte: "cancelled_by_correction", "correction_chain_indeterminate", "not_sent", "no_recipient", "no_level_due", "not_overdue", "processing_restricted" |
Verwendet von:
GET /invoices/{id}/reminders/preview
DunningNextAction object
The SERVER-COMPUTED next-action descriptor for one overdue invoice. web renders it verbatim — the Mahnstufe schedule stays server-side. Produced by the shared send-precondition helper so a future send path cannot drift from what the row hint shows.
| Feld | Typ | Beschreibung |
|---|---|---|
nextLevelKey erforderlich | string | null | The next level's key, or null when all reached levels are sent. |
nextLevelLabel erforderlich | string | null | The next level's label (the dynamic kebab item label), or null. |
sendable erforderlich | boolean | Whether the next level can be sent right now. |
blockedReason erforderlich | string | null | Why the next level is not sendable, or null when sendable is true. Werte: "cancelled_by_correction", "correction_chain_indeterminate", "not_sent", "no_recipient", "no_level_due", "all_sent", "processing_restricted" |
nextLevelAvailableFrom erforderlich | string (date) | null | ISO date the next level becomes due, when it is not yet due (no_level_due), else null. |
Verwendet von:
GET /dunning/overdue
DunningLevel object
One Mahnstufe of a policy's escalation ladder (a snapshotted config unit).
| Feld | Typ | Beschreibung |
|---|---|---|
sequence erforderlich | integer | 0 = Zahlungserinnerung, 1 = 1. Mahnung, … (the ordering key). Bereich: ≥ 0 |
key erforderlich | string | Stable machine key, e.g. 'zahlungserinnerung' | 'mahnung_1'. |
label erforderlich | string | Human label, e.g. '1. Mahnung'. |
dayOffset erforderlich | integer | Days after the effective due date at which this level becomes due. Bereich: ≥ 0 |
newDeadlineDays erforderlich | integer | New payment deadline this level sets, in days from the send date. Bereich: ≥ 1 |
subjectTemplate erforderlich | string | German subject template (placeholder vocab). |
bodyHtmlTemplate erforderlich | string | German HTML body template (placeholder vocab). |
Verwendet von:
GET /dunning/policy , PUT /dunning/policy , PATCH /dunning/policy , PUT /dunning/policy/charges
ReminderHistoryItem object
One reminder in the history — the immutable immutable reminder record, METADATA-ONLY. The rendered subject/body snapshot is retained on the row for evidence but NOT surfaced here (GDPR, no over-exposure).
| Feld | Typ | Beschreibung |
|---|---|---|
id erforderlich | string (uuid) | |
levelSequence erforderlich | integer | 0 = Zahlungserinnerung, 1 = 1. Mahnung, … |
levelKey erforderlich | string | |
levelLabel erforderlich | string | |
channel erforderlich | string | Werte: "email" |
recipientEmail erforderlich | string | Recipient at send time (never logged). |
invoiceNumber erforderlich | string | |
effectiveDueDate erforderlich | string (date) | The effective due date stated on the reminder (COALESCE(due_date, issue_date + 30)). |
daysOverdue erforderlich | integer | |
openAmountMinor erforderlich | integer | Stated open amount (minor units / cents). |
currency erforderlich | string | |
newPaymentDeadline erforderlich | string (date) | The new deadline this reminder set. |
interestChargedMinor erforderlich | integer | Interest/fee evidence — 0 unless interest and fees are switched on. |
feeChargedMinor erforderlich | integer | Interest/fee evidence — 0 unless interest and fees are switched on. |
interestRateBp erforderlich | integer | null | The rate (basis points) applied, or null when no interest was stated. |
interestDays erforderlich | integer | null | The day span the interest covered, or null when none was stated. |
createdAt erforderlich | string (date-time) | Sent-at timestamp. |
artifactAvailable erforderlich | boolean | Whether a FROZEN Mahnung PDF exists for this reminder (readable at |
Verwendet von:
GET /invoices/{id}/reminders
Nach oben · Alle Ressourcengruppen · OpenAPI-Spezifikation (YAML)