Einstellungen
Unternehmensprofil, DATEV-Zuordnung und E-Mail-Versand (SMTP) konfigurieren.
Company profile, DATEV mapping, and email/SMTP configuration.
Operationen
-
GET/settings/companyGet company profile (seller master data and invoice settings) -
PUT/settings/companyCreate or update company profile (upsert) -
PATCH/settings/companyPartially update company settings (§19 Kleinunternehmer flag) -
GET/settings/auto-reconcileIs automatic booking authorised for this company and environment? -
PUT/settings/auto-reconcileGrant or withdraw the authority to book matched credits automatically -
GET/settings/datev-mappingGet the current (or a specific historical) DATEV mapping config -
PUT/settings/datev-mappingCreate a new immutable DATEV mapping-config version -
PUT/settings/invoice-numberingSet the invoice-number format (prefix and minimum length) -
PUT/settings/invoice-number-counterSet the invoice-number counter -
GET/settings/emailRead the entity's SMTP/email settings (password never returned) -
PUT/settings/emailCreate or replace the entity's SMTP/email settings -
PUT/settings/email/passwordReplace the stored SMTP password, and nothing else -
POST/settings/email/testSend a one-off test email using the saved SMTP settings -
GET/settings/sending/reply-toRead the reply address for platform-provided sending -
PUT/settings/sending/reply-toSet the reply address and start confirming it -
POST/settings/sending/reply-to/resendSend a fresh confirmation code for the pending reply address -
POST/settings/sending/verify-reply-toConfirm the pending reply address with the six-digit code -
GET/settings/sendingRead who the recipient will see as sender, before the first send -
POST/settings/sending/acknowledgeAcknowledge the sender strings and switch on platform-provided sending -
POST/public/sending/verify-reply-toConfirm a reply address from the emailed link (no sign-in required)
Get company profile (seller master data and invoice settings)
GET /settings/company
The whole profile as stored. The read returns more keys than the whole-profile PUT accepts, and the asymmetry is deliberate. Seven of the returned keys are not part of the upsert body: id, createdAt and updatedAt are server-owned and read-only everywhere; isKleinunternehmer is written only through PATCH /settings/company (a legally significant flag with its own audit row); invoicePrefix and invoiceNumberPadding are written only through PUT /settings/invoice-numbering; and invoiceNumberCounter only through PUT /settings/invoice-number-counter. Sending any of them back in the PUT body is refused with 400 validation_error naming each key in issues[] — never silently dropped — so a read-modify-write caller must strip those seven before writing.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Antworten
-
200The company profile
application/jsonCompanyProfile -
404No company profile configured yet
Create or update company profile (upsert)
PUT /settings/company
A whole-object save: a field left out is authored as absent and clears (never a per-field exception). The body is strict — a key that is not in UpsertCompanyProfile is refused with 400 validation_error and named in issues[], including the seven keys the GET returns but this operation does not own: id, createdAt, updatedAt (read-only); isKleinunternehmer (owned by PATCH /settings/company); invoicePrefix and invoiceNumberPadding (owned by PUT /settings/invoice-numbering); invoiceNumberCounter (owned by PUT /settings/invoice-number-counter). Those narrow saves exist so a profile save can never move a numbering series or the § 19 flag as a side effect.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Request-Body erforderlich
application/json UpsertCompanyProfile
Antworten
-
200The upserted company profile
application/jsonCompanyProfile -
400Validation error
application/jsonValidationError -
403insufficient_role— the caller is not anadminorownerof the company. Nothing is written.application/jsonValidationError
Partially update company settings (§19 Kleinunternehmer flag)
PATCH /settings/company
Owner/admin-gated, audit-logged partial update. v1 carries exactly the isKleinunternehmer flag (legally significant — it governs §14 evaluation and is snapshotted onto every future invoice at creation). Distinct from the whole-profile PUT; unknown keys are rejected.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Request-Body erforderlich
application/json PatchCompanyProfile
Antworten
-
200The updated company profile
application/jsonCompanyProfile -
400Validation error
application/jsonValidationError -
403Caller lacks the required admin/owner role
-
404No company profile configured yet
Is automatic booking authorised for this company and environment?
GET /settings/auto-reconcile
⭐ THREE FACTS, NOT ONE. enabled is the company's own standing authorisation; capabilityEnabled is whether this environment can do it at all; effective is their AND. „Off because you have not switched it on" and „off because the platform has it off" are different sentences with different next actions, and a single boolean could not carry the difference.
It also returns the acknowledgement text itself, because the stored version must resolve to the exact words the person read — a surface holding its own copy of that text would be a second, unpinned source that can drift from what the server records.
Session-authenticated surfaces only; API keys are refused.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Antworten
-
200The company's consent state, the environment's capability, and the acknowledgement.
application/jsonAutoReconcileConsentState
Grant or withdraw the authority to book matched credits automatically
PUT /settings/auto-reconcile
The company's own standing authority that an unambiguously matched credit — an explicit invoice reference resolving to exactly ONE open invoice AND an exact-amount match — may be booked as paid with nobody pressing a button. Every other case still waits for a person, and this does not switch off the received-payments worklist.
Scoped to the calling session's company and environment, so an authorisation given in the sandbox can never authorise a live booking, and one company's never reaches another in the same account.
Granting requires acknowledgedVersion to equal the current acknowledgement version; WITHDRAWING never does, because stopping must not be harder than starting. Withdrawing binds on the next reported credit and changes nothing already booked.
⛔ Session-authenticated and admin: an acknowledgement is an act by a named person, and an API key names no person who could make it.
⛔ The environment capability can only ever SUBTRACT from this — authorising it while the environment has it off books nothing.
⚠ A source registered AFTER the authorisation was given is not covered by it: such a credit still waits for a person. uncoveredSourceCount reports how many, and the remedy is to confirm again on this same route, which re-covers every source that exists at that moment. There is deliberately no „include future sources" option.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Request-Body erforderlich
application/json SetAutoReconcileConsent
Antworten
-
200The resulting state. Idempotent in both directions: authorising an already-authorised company at the same version writes nothing new, and withdrawing when nothing is active is a success, not a conflict.
application/jsonAutoReconcileConsentState -
400Validation error — a malformed body, or a property this contract does not have.
application/jsonValidationError -
403insufficient_role(not anadmin), orcredential_not_accepted(an API-key caller — an acknowledgement names a person).application/jsonValidationError -
422auto_reconcile_acknowledgement_required— the request asked to GRANT andacknowledgedVersionwas absent or named a version that is no longer current, so the person acknowledged different words, or none. NOTHING WAS WRITTEN.details.currentDisclosureVersionnames the version to acknowledge. ⛔ Withdrawing never produces this.application/jsonValidationError
Get the current (or a specific historical) DATEV mapping config
GET /settings/datev-mapping
Without ?version, returns the latest stored config — or the version-0 built-in SKR default if nothing has ever been stored (zero-config behavior). ?version=N returns that exact historical version unchanged (?version=0 always resolves to the built-in default, which is never a stored row). The response always includes version-history metadata (latestVersion, isBuiltInDefault) alongside the config fields.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Parameter
| Parameter | In | Typ | Beschreibung |
|---|---|---|---|
version | Query | integer | A specific historical version to fetch. 0 = built-in SKR default. Bereich: ≥ 0 |
Antworten
-
200The resolved mapping config
application/jsonDatevMappingConfig -
400Invalid
versionquery parameterapplication/jsonValidationError -
404The requested
versiondoes not exist
Create a new immutable DATEV mapping-config version
PUT /settings/datev-mapping
Always creates a NEW version (append-only, never an in-place update) and returns it. Validates the config shape and, where statically checkable, DATEV constraints (a BU-Schlüssel set on a known Automatikkonto → 422 INVALID_MAPPING).
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Request-Body erforderlich
application/json DatevMappingConfigInput
Antworten
-
200The newly created version
application/jsonDatevMappingConfig -
400Validation error (malformed config shape)
application/jsonValidationError -
403insufficient_role— the caller is not anadminorownerof the company. Nothing is written.application/jsonValidationError -
422Invalid mapping — problem+json, code INVALID_MAPPING
application/problem+jsonInvalidMappingProblem
Set the invoice-number format (prefix and minimum length)
PUT /settings/invoice-numbering
Owner/admin only. The format is not part of the whole company-profile save: on that save an omitted property means "no value", and a numbering format cannot be absent, so it would have been reset to the shipped default by any save that did not mention it. Both properties are required here.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Request-Body erforderlich
application/json InvoiceNumberingFormat
Antworten
-
200The updated company profile
application/jsonCompanyProfile -
400Validation error
application/jsonValidationError -
409No company profile configured yet — create it first
-
422The requested prefix is reserved for sandbox documents. Sandbox and real invoices are numbered separately, and the sandbox series is marked by a reserved prefix; a real series may not use it, because a number identifies at most one document within a company. Nothing was written and the stored numbering format is unchanged.
application/jsonReservedInvoicePrefixError
Set the invoice-number counter
PUT /settings/invoice-number-counter
Owner/admin only. Deliberately separate from the format above: if the counter rode a wider body it would have to be restated on every format change, and restating a stale value re-issues numbers that already appear on issued documents.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Request-Body erforderlich
application/json InvoiceNumberCounter
Antworten
-
200The updated company profile
application/jsonCompanyProfile -
400Validation error
application/jsonValidationError -
409No company profile configured yet — create it first
-
422invoice_number_counter_rewind— the counter cannot be LOWERED once this entity has issued a numbered live invoice, because the series would re-issue numbers those documents already carry. Nothing was changed. Moving the counter FORWARD is unaffected and is the remedy ainvoice_number_conflictat issuance points at. Lowering the counter before the first issuance is permitted.application/jsonValidationError
Read the entity's SMTP/email settings (password never returned)
GET /settings/email
Non-secret settings for display. The SMTP password is write-only and is never read back. Session-authenticated surfaces only — API keys are refused.
Where test-mode sending is enabled on this deployment, a TEST-mode session is told which carrier test e-mails actually use: source is own_test (the settings saved for test mode, returned here), shared_live (none are saved for test mode, so the live settings carry test e-mails; they are returned here read-only and are changed in live mode), or platform_sandbox (no mail server in either mode: the platform's test sender carries them, and the body carries no settings fields). sandboxFallback gives the platform test sender's daily limit and today's count on every source. A live-mode session, and every session where test-mode sending is not enabled, gets the plain settings exactly as before, without source. Saving, the password and the test e-mail in a test-mode session always address the test-mode settings.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Antworten
-
200The saved email settings (no password).
application/jsonEmailSettings | SandboxPlatformEmailSettings -
404No email settings configured yet (
not_found).
Create or replace the entity's SMTP/email settings
PUT /settings/email
Whole-object replace — send the complete object every time. Every optional property here obeys one rule: omitting it stores nothing, so an omitted fromName or replyTo is CLEARED, changing the sender identity and the reply address on every message subsequently sent for this entity. Send the current values to keep them.
The SMTP password is required when creating the first settings object for this entity and mode (omit it then and the answer is 400 password_required). On a replace it is required exactly when the endpoint changes: a different host (compared case-insensitively, one trailing dot ignored), port or username without password is 422 email_password_required_for_endpoint_change and nothing is written, because the stored password is never sent to an endpoint it was not entered for; with password, the new endpoint and the password are stored together. A replace that keeps the endpoint and supplies password is 400 password_not_on_replace, and nothing is written; replace the stored password with PUT /settings/email/password. The password is encrypted at rest with the server's mail-credential key; 503 mail_key_missing when the server lacks it.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Request-Body erforderlich
application/json UpsertEmailSettings
Antworten
-
200The saved email settings (no password).
application/jsonEmailSettings -
400Validation error;
password_requiredon a first save without a password; orpassword_not_on_replacewhen settings already exist and the body keeps the endpoint but carries a password. In every case nothing was written.application/jsonValidationError -
403insufficient_role— the caller is not anadminorownerof the company. Nothing is written.application/jsonValidationError -
422email_password_required_for_endpoint_change— settings exist and the body changeshost,portorusernamewithoutpassword. The stored password is kept only for the endpoint it was entered for, so a new endpoint needs it restated in the same request. Nothing was written.application/jsonValidationError -
503mail_key_missing— the server has no mail-credential key configured to encrypt the password.application/jsonValidationError
Replace the stored SMTP password, and nothing else
PUT /settings/email/password
Replaces the stored SMTP password for this entity and mode. The single property is REQUIRED, so this body carries no omission question at all, and no other stored value can be reached from here — the sender identity, the reply address and the templates are untouched. Unknown properties are refused. The password is write-only: it is never read back by any endpoint. Session-authenticated surfaces only — API keys are refused.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Request-Body erforderlich
application/json SetEmailPassword
Antworten
-
204The stored password was replaced. No body — nothing readable changed, and the password is never returned.
-
400Validation error — the password is missing, empty or too long.
application/jsonValidationError -
403insufficient_role— the caller is not anadminorownerof the company. Nothing is written.application/jsonValidationError -
409email_settings_missing— no settings exist for this entity and mode, so there is no stored password to replace. Create the settings first withPUT /settings/email, which carries the password on that one call. Nothing was written.application/jsonValidationError -
503mail_key_missing— the server has no mail-credential key configured to encrypt the password.application/jsonValidationError
Send a one-off test email using the saved SMTP settings
POST /settings/email/test
Synchronous, bounded to 10 s. Uses the ALREADY-SAVED config (configure + PUT first). Not persisted to the outbox/log — a transient diagnostic.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only)
Request-Body erforderlich
application/json TestEmail
Antworten
-
200The test email was accepted by the SMTP server.
application/jsonTestEmailResult -
400A CONFIGURATION refusal — nothing was attempted, nothing was sent.
{ ok: false, error }whereerroris an invalid recipient, SMTP not configured yet,smtp_host_not_allowed(the saved host is an internal/link-local/loopback target, or a name resolving to one), orsmtp_tls_unavailable(the server offers no STARTTLS on thesecure: falsepath, so the refusal lands before AUTH and the stored SMTP password never reaches the wire). TLS is a floor, not an option: there is no opt-out.application/jsonTestEmailResult -
502SMTP/connection failure —
{ ok: false, error }. The send was attempted and the server rejected or dropped it (distinct from the 400 configuration refusals above).application/jsonTestEmailResult -
503mail_key_missing— the server has no mail-credential key configured.application/jsonTestEmailResult -
504The test send timed out (10 s) —
{ ok: false, error }.application/jsonTestEmailResult
Read the reply address for platform-provided sending
GET /settings/sending/reply-to
Under platform-provided sending, every field a receiving mail system authenticates belongs to the platform. The reply address is the ONLY sender field the customer controls, and it is used only after they have proven they hold it. This read publishes both facts separately: the address that has been PROVEN, and any address that is still WAITING for confirmation. Changing the address therefore never disturbs the proven one — nothing stops while a new address is being confirmed. Session-authenticated surfaces only; API keys are refused. Available only where platform-provided sending is enabled for the deployment.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only) - Verfügbarkeit
- noch nicht freigeschaltet
(
not-enabled)
Antworten
-
200The proven address and the pending one, either of which may be null.
application/jsonReplyToState
Set the reply address and start confirming it
PUT /settings/sending/reply-to
Records the address as PENDING and emails a six-digit confirmation code to it, together with a confirmation link. The address is not used for anything until it is confirmed. Calling this again replaces the pending address and issues a fresh code; a previously proven address is left untouched. Requires the admin role — deciding where a customer's replies land is configuration work.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only) - Verfügbarkeit
- noch nicht freigeschaltet
(
not-enabled)
Request-Body erforderlich
application/json SetReplyTo
Antworten
-
202The address is recorded as pending and a confirmation mail is queued. It is NOT yet in use.
application/jsonPendingReplyTo -
400Validation error — the address is not a valid email address.
application/jsonValidationError -
429system_mail_daily_ceiling_reached— this company has reached its daily limit of 50 invitation and reply-address confirmation emails (counted together, per company, over the Europe/Berlin calendar day: emails sent today plus emails still waiting to be sent). Nothing was created, changed or sent. The limit is fixed and resets at midnight Europe/Berlin;Retry-Aftergives the seconds until then andlimitthe number.-
Retry-AfterintegerSeconds until the next business day starts (Europe/Berlin midnight).
application/jsonobject -
Send a fresh confirmation code for the pending reply address
POST /settings/sending/reply-to/resend
Issues a NEW code for the address already awaiting confirmation and re-sends the mail. The previous code stops working immediately, so a code read from an older mail will be refused. A short minimum interval applies between two mails for the same address. Requires the admin role.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only) - Verfügbarkeit
- noch nicht freigeschaltet
(
not-enabled)
Antworten
-
202A fresh confirmation mail is queued.
application/jsonPendingReplyTo -
409reply_to_verification_not_pending— no address is waiting to be confirmed.application/jsonValidationError -
429reply_to_verification_resend_too_soon— a confirmation mail for this address was sent very recently; ORsystem_mail_daily_ceiling_reached— this company has reached its daily limit of 50 invitation and reply-address confirmation emails (Europe/Berlin calendar day; carrieslimitand aRetry-Afterof the seconds to midnight). Nothing was changed or sent in either case.-
Retry-AfterintegerPresent on
system_mail_daily_ceiling_reachedonly — seconds until the next business day starts.
application/jsonValidationError -
Confirm the pending reply address with the six-digit code
POST /settings/sending/verify-reply-to
The primary way to confirm a reply address: the person who entered it types the code from the mail into the same page. A code is accepted only for the account it was issued to, only until it expires, and only a small number of times before it is discarded and a new one must be requested. The number of remaining attempts is deliberately not disclosed. Requires the admin role.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only) - Verfügbarkeit
- noch nicht freigeschaltet
(
not-enabled)
Request-Body erforderlich
application/json VerifyReplyToCode
Antworten
-
200The address is confirmed and may now be used as the reply address.
application/jsonVerifiedReplyTo -
409reply_to_verification_not_pending— no address is waiting to be confirmed.application/jsonValidationError -
410reply_to_verification_expired— the code is no longer valid. Note that this can only be discovered on submission: nothing about a code is readable before it is used.application/jsonValidationError -
422reply_to_verification_code_mismatch— the code does not match.application/jsonValidationError -
429reply_to_verification_too_many_attempts— the code has been discarded; request a new one.application/jsonValidationError
Read who the recipient will see as sender, before the first send
GET /settings/sending
Which infrastructure carries this company's mail (activeSender), and — for platform-provided sending — the exact From display name, From address, reply address and disclosure sentence the recipient will see, computed by the server. A client renders these strings and computes none of them. Before the company has acknowledged them, the From address is a preview of the address that acknowledging will assign; reading it changes nothing and writes nothing. blockers lists, most blocking first, everything that stands between the company and platform-provided sending; capabilities says what the calling person may do. Any role may read. Session-authenticated surfaces only; API keys are refused. Available only where platform-provided sending is enabled for the deployment.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only) - Verfügbarkeit
- noch nicht freigeschaltet
(
not-enabled)
Antworten
-
200The sender the recipient will see, and what stands in the way.
application/jsonSendingSettings
Acknowledge the sender strings and switch on platform-provided sending
POST /settings/sending/acknowledge
Records that the calling person was shown the exact From display name, From address and reply address and confirmed them, and switches on platform-provided sending for this company and environment. The three strings the caller showed must equal, character for character, what GET /settings/sending returns at the moment of the request; if anything changed in between (for example the company name), the request is refused with sender_preview_stale and nothing is recorded — read the settings again and show the new strings. Nothing is sent by this request, and invoices issued before it are not mailed. Repeating it while sending is already switched on with the same strings answers 200 and records nothing new. Requires the admin role; an acknowledgement names a person, so API keys are refused. Every refusal leaves nothing recorded.
- Erforderlicher Scope
- keiner
- Zugang
- nur mit angemeldeter Sitzung – ein API-Schlüssel wird abgelehnt
(
oidc-only) - Verfügbarkeit
- noch nicht freigeschaltet
(
not-enabled)
Request-Body erforderlich
application/json AcknowledgeSending
Antworten
-
200Already switched on with these strings — nothing new was recorded.
application/jsonSendingSettings -
201Acknowledged; platform-provided sending is now on for this company and environment.
application/jsonSendingSettings -
400Validation error — a malformed body, or a property this contract does not have.
application/jsonValidationError -
403insufficient_role(not anadmin), orcredential_not_accepted(an API-key caller).application/jsonValidationError -
409send_unavailable_in_test_mode(a test-environment session) ·no_sending_domain_available·sending_paused·sending_identity_suspended·sender_preview_stale(the shown strings differ from what the server computes now) ·sending_identity_collision(the sender address could not be assigned). Nothing was recorded.application/jsonValidationError -
422company_name_missing·company_name_unusable(a name that cannot be used as a sender name) ·reply_to_missing(no reply address) ·reply_to_unverified(only an unconfirmed one). Nothing was recorded.application/jsonValidationError
Confirm a reply address from the emailed link (no sign-in required)
POST /public/sending/verify-reply-to
The fallback path, for the common case where the mailbox being confirmed is a shared accounting inbox opened by somebody who is not signed in and may not be a user of the account at all. It is reachable without any credential, and the single-use token from the mail is the only thing that identifies the request. It is a POST on purpose and there is no GET equivalent: mail-security systems fetch every link in an incoming message, and a single-use link would be spent before the recipient ever saw it. For the same reason the page carrying this form performs no action and issues no request until a person deliberately submits it. The endpoint is rate limited per client address.
- Erforderlicher Scope
- keiner
- Zugang
- ohne Anmeldung
(
public) - Verfügbarkeit
- noch nicht freigeschaltet
(
not-enabled)
Request-Body erforderlich
application/json VerifyReplyToToken
Antworten
-
200The address is confirmed.
application/jsonVerifiedReplyTo -
410reply_to_verification_expired— the link is no longer valid. The same answer is given for a token that never existed: telling the two apart would turn this endpoint into a way to probe which links exist, and the remedy is the same either way.application/jsonValidationError -
429Too many confirmation attempts from this client address.
Datenmodelle
Jedes Datenmodell dieser Gruppe einmal, mit allen Feldern – auch den verschachtelten. Verschachtelte Objekte sind aufklappbar; ein benannter Typ verweist auf seinen eigenen Abschnitt.
CompanyProfile object
Singleton company profile: seller master data and invoice numbering settings. Created via PUT /settings/company; absent until configured.
| Feld | Typ | Beschreibung |
|---|---|---|
id erforderlich | string (uuid) | |
sellerName erforderlich | string | |
sellerAddressLine1 | string | null | |
sellerPostalCode | string | null | |
sellerCity | string | null | |
sellerCountryCode | string | null | ISO 3166-1 alpha-2 |
sellerVatId | string | null | USt-IdNr |
logoUrl | string (uri) | null | |
taxNumber | string | null | Steuernummer |
isKleinunternehmer erforderlich | boolean | (§19 UStG) seller is a Kleinunternehmer. Set via the owner/admin-gated, audit-logged PATCH /settings/company. Snapshotted onto each invoice's |
paymentIban | string | null | |
paymentBic | string | null | |
paymentAccountHolder | string | null | |
paymentBankName | string | null | |
invoicePaymentQrEnabled | boolean | null | Print an EPC069-12 payment QR code (GiroCode) on invoice PDFs, beside the bank details. null means off. |
invoiceDateFormat erforderlich | string | Date segment inserted between prefix and counter. '' = no date; 'yyyyMMdd' = compact date, e.g. "R2026062200001" Werte: "", "yyyyMMdd" |
contactName | string | null | |
contactEmail | string (email) | null | |
contactPhone | string | null | |
defaultNotes | string | null | Default invoice notes prepopulated when no explicit notes are given |
invoicePrefix erforderlich | string | Prefix for auto-numbered invoices, e.g. "R" |
invoiceNumberPadding erforderlich | integer | Zero-pad width for the counter, e.g. 5 → "R00001" |
invoiceNumberCounter erforderlich | integer | Current counter value (incremented atomically on each invoice) |
createdAt erforderlich | string (date-time) | |
updatedAt erforderlich | string (date-time) |
Verwendet von:
GET /settings/company , PUT /settings/company , PATCH /settings/company , PUT /settings/invoice-numbering , PUT /settings/invoice-number-counter
UpsertCompanyProfile object
Replace the company profile. This body describes the WHOLE object: leaving an optional property out states that the property has no value, and the stored value is replaced with nothing. It is never kept, and it is never replaced by a value you did not send. Send every property you want to keep.
Unknown properties are refused rather than ignored, so a request written against an older version of this body is told, instead of silently losing the properties it sent.
The invoice-number prefix, the minimum number length and the counter are NOT part of this body: none of them has a "no value" state, and rewinding the counter would re-issue invoice numbers that already appear on issued documents. They have their own saves — PUT /settings/invoice-numbering and PUT /settings/invoice-number-counter. The small-business tax indicator likewise has its own save, PATCH /settings/company.
| Feld | Typ | Beschreibung |
|---|---|---|
sellerName erforderlich | string | Länge: min. 1 |
sellerAddressLine1 | string | null | |
sellerPostalCode | string | null | |
sellerCity | string | null | |
sellerCountryCode | string | null | ISO 3166-1 alpha-2 Länge: max. 2 |
sellerVatId | string | null | |
logoUrl | string (uri) | null | |
registerCourt | string | null | Länge: max. 200 |
registerNumber | string | null | Länge: max. 200 |
managingDirector | string | null | Länge: max. 200 |
website | string | null | Länge: max. 200 |
taxNumber | string | null | Steuernummer |
paymentIban | string | null | |
paymentBic | string | null | |
paymentAccountHolder | string | null | |
paymentBankName | string | null | |
invoicePaymentQrEnabled | boolean | null | Print an EPC069-12 payment QR code (GiroCode) on invoice PDFs. Omitted stores no value, and no value means off. The QR appears only on EUR invoices asking for a SEPA credit transfer that carry a payment IBAN; a direct-debit (collected) document never carries one. |
invoiceDateFormat | string | Whether the issue date is part of the invoice number. Omitted means no date segment, which is this property's "no value". Werte: "", "yyyyMMdd" |
contactName | string | null | |
contactEmail | string (email) | null | |
contactPhone | string | null | |
defaultNotes | string | null | |
defaultTitle | string | null | Länge: max. 500 |
defaultText | string | null | Länge: max. 5000 |
Verwendet von:
PUT /settings/company
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:
PUT /settings/company , PATCH /settings/company , PUT /settings/auto-reconcile , GET /settings/datev-mapping , PUT /settings/datev-mapping , PUT /settings/invoice-numbering , PUT /settings/invoice-number-counter , PUT /settings/email , PUT /settings/email/password , PUT /settings/sending/reply-to , POST /settings/sending/reply-to/resend , POST /settings/sending/verify-reply-to , POST /settings/sending/acknowledge , POST /public/sending/verify-reply-to
PatchCompanyProfile object
Partial update of company settings. v1 carries exactly the §19 Kleinunternehmer flag. Additional properties are rejected.
| Feld | Typ | Beschreibung |
|---|---|---|
isKleinunternehmer erforderlich | boolean | Whether the seller is a Kleinunternehmer (§19 UStG). |
Verwendet von:
PATCH /settings/company
AutoReconcileConsentState object
⭐ THREE BOOLEANS, NOT ONE. enabled is the company's own authorisation, capabilityEnabled is whether this environment can do it at all, and effective is their AND. The two „off" states must be distinguishable on the screen: „you have not switched it on" and „this environment has it off" are different sentences with different next actions. ⛔ Never render a visible-but-dead control.
| Feld | Typ | Beschreibung |
|---|---|---|
enabled erforderlich | boolean | The company's own standing authorisation for THIS company and THIS environment. Default false for every company, existing and new — there is no opt-out variant of this capability, no backfill, and no inference from a credit somebody once confirmed by hand. |
capabilityEnabled erforderlich | boolean | Whether this environment can perform automatic booking at all. |
effective erforderlich | boolean |
|
grantedAt | string (date-time) | null | When it was authorised. Null when it is not. |
grantedByUserId | string (uuid) | null | The person who authorised it. ⭐ The company can read this back later: an authorisation that cannot evidence who gave it, and when, is not an authorisation. |
acknowledgedVersion | string | null | The acknowledgement version that person accepted. ⚠ May be OLDER than |
currentDisclosureVersion erforderlich | string | The version a new grant must acknowledge. |
uncoveredSourceCount erforderlich | integer | ⭐ How many ACTIVE reporting sources for this company were registered AFTER the authorisation was given, and are therefore NOT covered by it. A credit from such a source still waits for a person — the failure direction is more clicks, never money booked unseen.
⛔ NOT AN ERROR STATE. An uncovered source is a correct configuration, not a fault, and the remedy is to confirm again on the PUT, which re-covers every source that exists at that moment.
⚠ A count, never an identifier: the source listing is administrator-only and projects the receiving address, so an id here would widen that surface by accident. |
disclosure erforderlich | AutoReconcileAcknowledgement | |
integrationNote erforderlich | string | ⭐ A note to show BESIDE the control, and ⛔ NOT part of what is acknowledged — it is outside |
Verwendet von:
GET /settings/auto-reconcile , PUT /settings/auto-reconcile
SetAutoReconcileConsent object
⛔ A NARROW BODY WITH THREE PROPERTIES, deliberately never a member of any whole-object settings save. This product has twice shipped a fat save in which omitting one field KEPT its value while omitting a sibling CLEARED it — once rewriting a statutory late-payment amount — and the remedy both times was for the dangerous field to leave the save onto a route of its own. A standing authority to book money unattended is the most dangerous field any save here will ever carry.
| Feld | Typ | Beschreibung |
|---|---|---|
enabled erforderlich | boolean | True grants the authority; false withdraws it. |
acknowledgedVersion | string | REQUIRED when Länge: max. 32 |
reaffirm | boolean | ⭐ An EXPLICIT RE-AFFIRMATION. With Standard: false |
Verwendet von:
PUT /settings/auto-reconcile
DatevMappingConfig object
| Feld | Typ | Beschreibung |
|---|---|---|
skr erforderlich | string | Werte: "03", "04" |
sachkontenlaenge erforderlich | integer | Bereich: ≥ 4, ≤ 8 |
beraternummer | string | 0–7 digits |
mandantennummer | string | 0–5 digits |
wjStartMonth erforderlich | integer | Bereich: ≥ 1, ≤ 12 |
festschreibung erforderlich | integer | Werte: 0, 1 |
debitorStrategy erforderlich | string | Werte: "collective", "per_customer" |
collectiveDebitorKonto | integer | Required when debitorStrategy = collective. |
debitorAccounts | object | customerId -> Debitorkonto. Required when debitorStrategy = per_customer. |
revenueAccounts erforderlich | Array<DatevRevenueAccountMapping> | Elemente: min. 1 |
version erforderlich nur lesbar | integer | 0 = built-in SKR default (never a stored row). |
createdAt erforderlich | string (date-time) | null | null for the version-0 built-in default. |
createdBy erforderlich | string | null | Verified OIDC sub, or null when the record was not created by a signed-in user (an automated or built-in default). |
latestVersion erforderlich | integer | Highest version ever stored; 0 if nothing has been stored yet. |
isBuiltInDefault erforderlich | boolean |
Verwendet von:
GET /settings/datev-mapping , PUT /settings/datev-mapping
DatevMappingConfigInput object
debitorStrategy determines which of collectiveDebitorKonto / debitorAccounts is required (modeled as a discriminated union server-side).
| Feld | Typ | Beschreibung |
|---|---|---|
skr erforderlich | string | Werte: "03", "04" |
sachkontenlaenge erforderlich | integer | Bereich: ≥ 4, ≤ 8 |
beraternummer | string | 0–7 digits |
mandantennummer | string | 0–5 digits |
wjStartMonth erforderlich | integer | Bereich: ≥ 1, ≤ 12 |
festschreibung erforderlich | integer | Werte: 0, 1 |
debitorStrategy erforderlich | string | Werte: "collective", "per_customer" |
collectiveDebitorKonto | integer | Required when debitorStrategy = collective. |
debitorAccounts | object | customerId -> Debitorkonto. Required when debitorStrategy = per_customer. |
revenueAccounts erforderlich | Array<DatevRevenueAccountMapping> | Elemente: min. 1 |
Verwendet von:
PUT /settings/datev-mapping
InvalidMappingProblem object
PUT /settings/datev-mapping with a BU-Schlüssel set on a known DATEV Automatikkonto for the config's skr.
| Feld | Typ | Beschreibung | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
type | string | ||||||||||
title | string | ||||||||||
status | integer | ||||||||||
detail | string | ||||||||||
code erforderlich | string | Werte: "INVALID_MAPPING" | |||||||||
items erforderlich | Array<object> | The offending account(s). Felder
|
Verwendet von:
PUT /settings/datev-mapping
InvoiceNumberingFormat object
The invoice-number format. Both properties are required: a numbering format has no "no value" state, so a request that omits one is refused rather than silently reformatting a numbering series that is already in use. Unknown properties are refused. The counter is deliberately not here — see PUT /settings/invoice-number-counter.
| Feld | Typ | Beschreibung |
|---|---|---|
invoicePrefix erforderlich | string | The text every invoice number starts with, for example "RE-". Länge: min. 1, max. 20 |
invoiceNumberPadding erforderlich | integer | The minimum number of digits the counter is padded to, for example 5 for "RE-00042". Bereich: ≥ 1, ≤ 10 |
Verwendet von:
PUT /settings/invoice-numbering
ReservedInvoicePrefixError object
422 body when the requested live invoice-number prefix falls inside the prefix reserved for sandbox documents. Sandbox and real invoices are numbered separately so that a sandbox document can never take a number a real one needs; a number identifies at most one document within a company, so the two series may not share a prefix. Nothing was written and the stored numbering format is unchanged.
| Feld | Typ | Beschreibung |
|---|---|---|
error erforderlich | string | Werte: "invoice_prefix_reserved" |
message | string |
Verwendet von:
PUT /settings/invoice-numbering
InvoiceNumberCounter object
The count of invoices issued so far; the next invoice takes this number plus one. It has its own save because it must never move as a side-effect of another save: lowering it re-issues numbers that already appear on issued documents.
| Feld | Typ | Beschreibung |
|---|---|---|
invoiceNumberCounter erforderlich | integer | Bereich: ≥ 0 |
Verwendet von:
PUT /settings/invoice-number-counter
EmailSettings object
Non-secret SMTP settings for display. The password is write-only and is NEVER returned.
| Feld | Typ | Beschreibung |
|---|---|---|
host erforderlich | string | |
port erforderlich | integer | Bereich: ≥ 1, ≤ 65535 |
secure erforderlich | boolean | |
username erforderlich | string | |
fromName | string | null | |
fromEmail erforderlich | string (email) | |
replyTo | string (email) | null | |
subjectTemplate erforderlich | string | Placeholders: {invoiceNumber} {buyerName} {issueDate} {currency} {totalGross} {sellerName}. |
bodyTemplateHtml erforderlich | string | |
source | string | Present only on a test-mode read where test-mode sending is enabled. Werte: "own_test", "shared_live" |
sandboxFallback | SandboxFallback |
Verwendet von:
GET /settings/email , PUT /settings/email
SandboxPlatformEmailSettings object
A test-mode read where test-mode sending is enabled and no mail server is set up in either mode: the platform's test sender carries test e-mails, only to confirmed reply addresses and to people who belong to the account, and at most sandboxFallback.dailyCap a day.
| Feld | Typ | Beschreibung |
|---|---|---|
source erforderlich | string | Werte: "platform_sandbox" |
sandboxFallback erforderlich | SandboxFallback |
Verwendet von:
GET /settings/email
UpsertEmailSettings object
Create/replace SMTP settings. This is a WHOLE-OBJECT REPLACE: send the complete object every time. Every optional property obeys ONE rule — omitting it stores nothing — except password, which is not part of a replace at all; read its description before sending it.
| Feld | Typ | Beschreibung |
|---|---|---|
host erforderlich | string | Länge: min. 1, max. 255 |
port erforderlich | integer | Bereich: ≥ 1, ≤ 65535 |
secure erforderlich | boolean | |
username erforderlich | string | Länge: min. 1, max. 255 |
password nur schreibbar | string | REQUIRED on the CREATE, and on a replace that changes the endpoint. Send it when no settings exist yet for this entity and mode — the stored credential cannot be absent. Once settings exist, a replace that changes Länge: min. 1, max. 1024 |
fromName | string | Optional display name in the Länge: max. 200 |
fromEmail erforderlich | string (email) | Länge: max. 254 |
replyTo | string (email) | null | Optional |
subjectTemplate erforderlich | string | Länge: min. 1, max. 998 |
bodyTemplateHtml erforderlich | string | Länge: min. 1, max. 50000 |
Verwendet von:
PUT /settings/email
SetEmailPassword object
The SMTP password on its own. Required — this body has no optional property and therefore no omission rule. No other stored value can be written through it.
| Feld | Typ | Beschreibung |
|---|---|---|
password erforderlich nur schreibbar | string | The new SMTP password. Write-only; it is never read back. Länge: min. 1, max. 1024 |
Verwendet von:
PUT /settings/email/password
TestEmail object
The recipient of a one-off test email.
| Feld | Typ | Beschreibung |
|---|---|---|
to erforderlich | string (email) | Länge: max. 254 |
Verwendet von:
POST /settings/email/test
TestEmailResult object
Result of a test send. { ok: true } on success; { ok: false, error } with a short, safe message on any failure.
| Feld | Typ | Beschreibung |
|---|---|---|
ok erforderlich | boolean | |
error | string |
Verwendet von:
POST /settings/email/test
ReplyToState object
The reply address for platform-provided sending, in its two independent states. A proven address stays proven while a different one is being confirmed, so changing the address never interrupts sending.
| Feld | Typ | Beschreibung |
|---|---|---|
verified erforderlich | VerifiedReplyTo | null | The address most recently proven to belong to this customer. |
pending erforderlich | PendingReplyTo | null | An address awaiting confirmation. Absent once it expires — expiry is not otherwise observable. |
Verwendet von:
GET /settings/sending/reply-to
SetReplyTo object
The address replies should go to. Exactly one field, and it is required — there is no omission rule to get wrong here.
| Feld | Typ | Beschreibung |
|---|---|---|
address erforderlich | string (email) | The domain part is lower-cased; the part before the @ is left exactly as sent, because it is case-sensitive by definition and folding it would address a different mailbox on the servers that honour that. Länge: max. 254 |
Verwendet von:
PUT /settings/sending/reply-to
PendingReplyTo object
| Feld | Typ | Beschreibung |
|---|---|---|
address | string (email) | |
expiresAt erforderlich | string (date-time) | When the confirmation code and its companion link stop being accepted. Both share one lifetime, so the validity stated in the mail is true whichever way the recipient confirms. |
Verwendet von:
PUT /settings/sending/reply-to , POST /settings/sending/reply-to/resend
VerifyReplyToCode object
| Feld | Typ | Beschreibung |
|---|---|---|
code erforderlich | string | The six-digit code from the confirmation mail. Spaces are ignored, so a code read out in pairs can be typed as it was heard; nothing else is corrected. Muster: ^[0-9]{6}$ |
Verwendet von:
POST /settings/sending/verify-reply-to
VerifiedReplyTo object
| Feld | Typ | Beschreibung |
|---|---|---|
address erforderlich | string (email) | |
verifiedAt | string (date-time) | When the address was proven. |
Verwendet von:
POST /settings/sending/verify-reply-to , POST /public/sending/verify-reply-to
SendingSettings object
Who carries this company's mail and, for platform-provided sending, the exact strings the recipient will see. Every string is computed by the server; a client renders them and derives nothing.
| Feld | Typ | Beschreibung | |||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
activeSender erforderlich | string | Which infrastructure carries the next message: the company's own mail server ( Werte: "platform", "tenant_smtp", "none" | |||||||||||||||||||||||||||||||||||||||||||||||||||
platform erforderlich | object | Felder
| |||||||||||||||||||||||||||||||||||||||||||||||||||
sendingState erforderlich | string | The organisation's sending standing. Werte: "active", "probation", "paused" | |||||||||||||||||||||||||||||||||||||||||||||||||||
sendingStateReason erforderlich | string | null | Why sending is paused or on probation; | |||||||||||||||||||||||||||||||||||||||||||||||||||
capabilities erforderlich | object | Felder
|
Verwendet von:
GET /settings/sending , POST /settings/sending/acknowledge
AcknowledgeSending object
The three strings the person was shown, exactly as GET /settings/sending returned them, and where they were shown. Compared character for character — never trimmed or normalised.
| Feld | Typ | Beschreibung |
|---|---|---|
shownFromDisplayName erforderlich | string | Länge: max. 512 |
shownFromAddress erforderlich | string | Länge: max. 512 |
shownReplyTo erforderlich | string | Länge: max. 512 |
surface erforderlich | string |
Werte: "web_send", "dashboard" |
Verwendet von:
POST /settings/sending/acknowledge
VerifyReplyToToken object
| Feld | Typ | Beschreibung |
|---|---|---|
token erforderlich | string | The single-use token from the confirmation link. Länge: min. 16, max. 512 |
Verwendet von:
POST /public/sending/verify-reply-to
AutoReconcileAcknowledgement object
The acknowledgement a person is shown AT the control, as the server holds it. ⛔ None of it may be placed behind a link, and the control may never be pre-ticked — its activation IS the acknowledgement. ⭐ It is published BY THE API rather than written into each surface because the stored version must resolve to the exact words that person read. A surface carrying its own copy would be a second source that can silently drift from the version the server records against the act.
| Feld | Typ | Beschreibung | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
version erforderlich | string | The version a grant must acknowledge. Changes whenever a single word of the text does. | |||||||||
voiceStatus erforderlich | string | ⛳ Werte: "provisional", "approved" | |||||||||
propositions erforderlich | Array<object> | One entry per thing the acknowledgement must convey, in reading order. Rendered in full, in order, at the control — the identifiers exist so a surface can lay the sentences out, never so it can choose a subset. Felder
|
Verwendet von:
GET /settings/auto-reconcile , PUT /settings/auto-reconcile
DatevRevenueAccountMapping object
| Feld | Typ | Beschreibung |
|---|---|---|
taxRatePercent erforderlich | string | |
vatCategory | string | Optional EN-16931 BT-118 category qualifier. Absent = a rate-only entry (standard 19%/7% + legacy configs); present = a category-qualified slot, e.g. Werte: "S", "E", "AE", "K", "G", "Z", "O" |
konto erforderlich | integer | |
buSchluessel | integer | null |
Verwendet von:
GET /settings/datev-mapping , PUT /settings/datev-mapping
SandboxFallback object
The platform's test sender: its daily limit per company and how much of it is used today (e-mails sent today plus e-mails still waiting, Europe/Berlin calendar day). Only e-mails the platform's test sender carries count; e-mails sent through the company's own mail server do not.
| Feld | Typ | Beschreibung |
|---|---|---|
dailyCap erforderlich | integer | Bereich: ≥ 1 |
sentToday erforderlich | integer | Bereich: ≥ 0 |
Verwendet von:
GET /settings/email , PUT /settings/email
Nach oben · Alle Ressourcengruppen · OpenAPI-Spezifikation (YAML)