SharpMailserver SHARPMAILSERVER
Kapitel 12 Clients, Groupware & CLI Admin: #pApiAuth

Vollständige API- & CLI-Feld-Referenz: Alle 12 Objekttypen, REST-Endpunkte & POST /api/v1/send

Dieses Nachschlagewerk dokumentiert jedes einzelne JSON-Feld, jeden Datentyp, alle Enum-Werte, Standardwerte und Mindest-Rollen (RBAC) für sämtliche 12 Management-Objekte (/api/admin/cli/objects/{type} & sharpmail-cli) sowie für den transaktionalen E-Mail-Versand (POST /api/v1/send). Nutze das Filterfeld rechts über der Tabelle, um in Echtzeit nach Feldnamen wie dkimSigningMode, tlsMode, allowedCidrs oder warmingEnabled zu suchen.

Praxis-Tipp & Architektur-Hinweis

Live-Introspektion direkt im Terminal oder per HTTP: Jeder SharpMailserver stellt dieses komplette Schema zusätzlich maschinenlesbar unter GET /api/admin/cli/schema (inkl. SHA-256-Versionsheader X-SharpMail-Schema-Version) bereit. Im Terminal zeigt dir sharpmail-cli describe <Type> (z. B. sharpmail-cli describe Domain oder sharpmail-cli describe SmtpQueue) jederzeit alle Felder offline-gecached an.

Transaktionaler Versand

TransactionalSendRequest (POST /api/v1/send)

Schlüssel: Idempotency-Key RBAC: User+
13 Felder

Hochperformanter HTTP-JSON-Versandendpunkt für Shops, ERP, CRM und 2FA-Codes mit Kategorie-Priorisierung, IP-Warming, Suppression-Vorprüfung und 24h-Idempotenz.

POST /api/v1/send Sendet E-Mail (UTF-8 Multipart/Alternative + Anhänge) über die Outbound-Pipeline
POST /api/v1/unsubscribe/{token} Öffentlicher RFC-8058 One-Click-Unsubscribe-Endpunkt (DKIM-signierter Token)
{ } Objekt-Schema & typisierte Felder application/json · camelCase
├─ from string OPTIONAL
Standard: Key senderAddress
Absenderadresse (z. B. "Rechnung <rechnung@firma.de>"). Bei Role=User-Keys mit fester senderAddress automatisch vorbelegt.
├─ to string[] PFLICHTFELD
Array der Empfänger-E-Mail-Adressen (mindestens 1 Empfänger erforderlich).
├─ cc string[] OPTIONAL
Standard: []
Optionale Kopie-Empfänger (Carbon Copy).
├─ bcc string[] OPTIONAL
Standard: []
Optionale Blindkopie-Empfänger (Blind Carbon Copy).
├─ replyTo string OPTIONAL
Abweichende Antwortadresse (Reply-To Header).
├─ subject string PFLICHTFELD
Betreffzeile der E-Mail (UTF-8).
├─ textBody string OPTIONAL
Reintext-Inhalt (text/plain). Mindestens textBody oder htmlBody muss übergeben werden.
├─ htmlBody string OPTIONAL
HTML-Inhalt (text/html). Für 10/10 Zustellbarkeit immer gemeinsam mit textBody senden.
├─ category string OPTIONAL
Standard: transactional
Steuert Queue-Priorität, IP-Warming-Bypass und Empfänger-Anbieter-Kontingent.
Enum:"critical""transactional""notification""marketing"
├─ overflowMode string OPTIONAL
Standard: DeferQueue
Verhalten bei ausgeschöpftem Stunden-Kontingent des Ziel-Providers (sanftes Pacing vs. HTTP 429 + Retry-After).
Enum:"DeferQueue""Reject429"
├─ idempotencyKey string OPTIONAL
Standard: Header Idempotency-Key
Eindeutiger Schlüssel (z. B. Rechnungsnummer inv-2026-90412) gegen doppelten Versand innerhalb von 24 Stunden.
├─ headers Record<string, string> OPTIONAL
Standard: {}
Zusätzliche benutzerdefinierte X-Header als Key-Value-Objekt.
├─ attachments SendAttachmentDto[] OPTIONAL
Standard: []
Array aus { fileName: string, contentType: string, base64Content: string }.
{
  "from": "Abrechnung <rechnung@firma.de>",
  "to": ["einkauf@kunde.de"],
  "cc": ["buchhaltung@firma.de"],
  "subject": "Ihre elektronische Rechnung RE-2026-90412",
  "category": "transactional",
  "overflowMode": "DeferQueue",
  "textBody": "Guten Tag,\nanbei erhalten Sie Ihre Rechnung RE-2026-90412.",
  "htmlBody": "<p>Guten Tag,</p><p>anbei erhalten Sie Ihre Rechnung <strong>RE-2026-90412</strong>.</p>",
  "headers": {
    "X-ERP-Document-Id": "RE-2026-90412"
  },
  "attachments": [
    {
      "fileName": "RE-2026-90412.pdf",
      "contentType": "application/pdf",
      "base64Content": "JVBERi0xLjcKJcfs..."
    }
  ]
}
# 1) Kleinstprivilegierten Sende-Key (Role=User) für rechnung@firma.de erstellen:
sharpmail-cli create ApiKey \
  --set label="ERP Rechnungsversand" \
  --set role=User \
  --set senderAddress=rechnung@firma.de \
  --set defaultCategory=transactional \
  --set allowedCidrs=10.20.0.0/16

# 2) Risikofreier Trockentest gegen die integrierte Sandbox-Sink-Domain:
# ok@sink.sharpmail.local | bounce@sink.sharpmail.local | defer@sink.sharpmail.local
curl -fsS -X POST "https://mail.firma.de/api/v1/send" \
  -H "Authorization: Bearer smk_01968f2a_..." \
  -H "Idempotency-Key: inv-2026-90412" \
  -H "Content-Type: application/json" \
  -d '{
    "from": "rechnung@firma.de",
    "to": ["einkauf@kunde.de"],
    "subject": "Ihre Rechnung RE-2026-90412",
    "category": "transactional",
    "textBody": "Guten Tag, anbei Ihre Rechnung RE-2026-90412.",
    "htmlBody": "<p>Guten Tag, anbei Ihre Rechnung <b>RE-2026-90412</b>.</p>"
  }'
using System.Net.Http.Headers;
using System.Net.Http.Json;

using var http = new HttpClient { BaseAddress = new Uri("https://mail.firma.de") };
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "smk_01968f2a_...");
http.DefaultRequestHeaders.Add("Idempotency-Key", "inv-2026-90412");

var response = await http.PostAsJsonAsync("/api/v1/send", new
{
    from = "rechnung@firma.de",
    to = new[] { "einkauf@kunde.de" },
    subject = "Ihre Rechnung RE-2026-90412",
    category = "transactional",
    textBody = "Guten Tag, anbei Ihre Rechnung RE-2026-90412.",
    htmlBody = "<p>Guten Tag, anbei Ihre Rechnung <strong>RE-2026-90412</strong>.</p>"
});
response.EnsureSuccessStatusCode();
Sammlungs-Objekt (CRUD)

Tenant

Schlüssel: slug RBAC: ServerAdmin+
11 Felder

Mandanten-Organisationseinheit mit isolierten Kontingenten für Domains, Postfächer, Speicherplatz (GiB) und Standard-GoBD-WORM-Aufbewahrung.

GET /api/admin/cli/objects/Tenant Listet alle Mandanten
GET /api/admin/cli/objects/Tenant/{slugOrId} Liest einen Mandanten per Slug oder UUID
POST /api/admin/cli/objects/Tenant Erstellt einen neuen Mandanten
PATCH /api/admin/cli/objects/Tenant/{slugOrId} Aktualisiert Mandanten-Limits im laufenden Betrieb
{ } Objekt-Schema & typisierte Felder application/json · camelCase
├─ id guid READ-ONLY
Standard: UUIDv7
Interne unveränderliche Mandanten-UUID.
├─ slug string PRIMÄRSCHLÜSSEL
Eindeutiger URL-sicherer Mandanten-Schlüssel (z. B. "default", "acme").
├─ name string PFLICHTFELD
Anzeigename des Unternehmens / Mandanten.
├─ isActive boolean OPTIONAL
Standard: true
Mandant aktivieren oder pausieren.
├─ maxDomains integer OPTIONAL
Standard: 100
Maximale Anzahl Domains in diesem Mandanten.
├─ maxPrincipals integer OPTIONAL
Standard: 10000
Maximale Anzahl Postfächer & Verteilerlisten.
├─ quotaGb integer OPTIONAL
Standard: 100
Speicherkontingent des Mandanten in GiB.
├─ outboundDailyLimit integer OPTIONAL
Standard: 25000
Maximale ausgehende E-Mails pro Tag über alle Konten des Mandanten.
├─ defaultLockMode string OPTIONAL
Standard: Normal
Standard-WORM-Archivmodus für neu angelegte Domains.
Enum:"Normal""Governance""Compliance""LegalHold"
├─ defaultRetentionDays integer OPTIONAL
Standard: 0
Standard-Aufbewahrungsdauer in Tagen (3650 = 10 Jahre GoBD).
├─ createdAtUtc datetime READ-ONLY
Erstellungszeitpunkt (UTC ISO-8601).
{
  "slug": "acme",
  "name": "ACME Logistik GmbH",
  "isActive": true,
  "maxDomains": 50,
  "maxPrincipals": 2500,
  "quotaGb": 250,
  "outboundDailyLimit": 25000,
  "defaultLockMode": "Compliance",
  "defaultRetentionDays": 3650
}
# Mandant anlegen:
sharpmail-cli create Tenant \
  --set slug=acme \
  --set name="ACME Logistik GmbH" \
  --set quotaGb=250 \
  --set defaultLockMode=Compliance \
  --set defaultRetentionDays=3650

# Mandant abfragen & Kontingent erhöhen:
sharpmail-cli get Tenant acme
sharpmail-cli update Tenant acme --set quotaGb=500
curl -fsS -X POST "https://mail.firma.de/api/admin/cli/objects/Tenant" \
  -H "Authorization: Bearer smk_..." \
  -H "Content-Type: application/json" \
  -d '{"slug":"acme","name":"ACME Logistik GmbH","quotaGb":250,"defaultLockMode":"Compliance","defaultRetentionDays":3650}'
var payload = new
{
    slug = "acme",
    name = "ACME Logistik GmbH",
    quotaGb = 250,
    defaultLockMode = "Compliance",
    defaultRetentionDays = 3650
};
using var res = await http.PostAsJsonAsync("/api/admin/cli/objects/Tenant", payload);
Sammlungs-Objekt (CRUD)

Domain

Schlüssel: name RBAC: TenantAdmin+
19 Felder

E-Mail-Domain inklusive automatischer Dual-DKIM-Schlüsselgenerierung (RSA-2048 + Ed25519), GoBD-WORM-Policy, Plus-Adressierung und Versandlimits.

GET /api/admin/cli/objects/Domain Listet alle Domains des Mandanten
GET /api/admin/cli/objects/Domain/{name} Liest Domain-Konfiguration & DKIM-Selektoren
POST /api/admin/cli/objects/Domain Erstellt Domain & generiert RSA-2048 + Ed25519 DKIM-Schlüssel
PATCH /api/admin/cli/objects/Domain/{name} Aktualisiert DKIM-Modus, Quotas oder GoBD-Aufbewahrung (0 ms Hot-Reload)
GET /api/admin/cli/dns/{name}?live=true Prüft MX, SPF, Dual-DKIM, DMARC, MTA-STS & DANE live
{ } Objekt-Schema & typisierte Felder application/json · camelCase
├─ id guid READ-ONLY
Standard: UUIDv7
Interne Domain-UUID.
├─ name string PRIMÄRSCHLÜSSEL
Vollständiger DNS-Domainname (z. B. "muster-logistik.de").
├─ tenant string OPTIONAL
Standard: default
Zugehöriger Mandanten-Slug oder Mandanten-GUID.
├─ isActive boolean OPTIONAL
Standard: true
Domain für Empfang und Versand aktiv.
├─ postmasterAddress string OPTIONAL
Standard: postmaster@<name>
RFC-5321-Postmaster- und Abuse-Kontaktadresse.
├─ dkimSigningMode string OPTIONAL
Standard: Dual
Aktiver DKIM-Signaturmodus (Dual signiert jede E-Mail parallel mit RSA-2048 und Ed25519).
Enum:"Rsa2048""Ed25519""Dual"
├─ dkimRsaSelector string OPTIONAL
Standard: s2026
DNS-Selektor für den RSA-2048-Schlüssel (<selector>._domainkey.<name>).
├─ dkimRsaDnsName string READ-ONLY
Standard: s2026._domainkey.<name>
Berechneter DNS-Record-Name für RSA-2048.
├─ dkimEd25519Selector string OPTIONAL
Standard: ed2026
DNS-Selektor für den Ed25519-Schlüssel (<selector>._domainkey.<name>).
├─ dkimEd25519DnsName string READ-ONLY
Standard: ed2026._domainkey.<name>
Berechneter DNS-Record-Name für Ed25519.
├─ retentionLockMode string OPTIONAL
Standard: Normal
GoBD-WORM-Archivschutz für alle Postfächer dieser Domain.
Enum:"Normal""Governance""Compliance""LegalHold"
├─ retentionDays integer OPTIONAL
Standard: 0
Aufbewahrungsdauer in Tagen (3650 = 10 Jahre gemäß § 147 AO / GoBD).
├─ quotaGb integer OPTIONAL
Standard: 50
Speicherlimit der Domain in GiB.
├─ maxMessageSizeMb integer OPTIONAL
Standard: 50
Maximale E-Mail-Größe in MiB.
├─ maxAccounts integer OPTIONAL
Standard: 1000
Maximale Anzahl Postfächer in dieser Domain.
├─ outboundDailyLimit integer OPTIONAL
Standard: 5000
Tageslimit ausgehender E-Mails für diese Domain.
├─ outboundHourlyLimit integer OPTIONAL
Standard: 1000
Stundenlimit ausgehender E-Mails für diese Domain.
├─ usePlusAddressing boolean OPTIONAL
Standard: true
Erlaubt Sub-Adressierung nach dem Muster name+projekt@domain.de.
├─ createdAtUtc datetime READ-ONLY
Erstellungszeitpunkt (UTC).
{
  "name": "muster-logistik.de",
  "tenant": "default",
  "isActive": true,
  "postmasterAddress": "postmaster@muster-logistik.de",
  "dkimSigningMode": "Dual",
  "dkimRsaSelector": "s2026",
  "dkimEd25519Selector": "ed2026",
  "retentionLockMode": "Compliance",
  "retentionDays": 3650,
  "quotaGb": 100,
  "maxMessageSizeMb": 50,
  "maxAccounts": 500,
  "outboundDailyLimit": 10000,
  "outboundHourlyLimit": 2000,
  "usePlusAddressing": true
}
# Domain mit Dual-DKIM und 10 Jahren GoBD-Compliance anlegen:
sharpmail-cli create Domain \
  --set name=muster-logistik.de \
  --set dkimSigningMode=Dual \
  --set retentionLockMode=Compliance \
  --set retentionDays=3650

# Fertige RFC-1035 BIND-Zonendatei exportieren & DNS live prüfen:
sharpmail-cli dns muster-logistik.de --bind > muster-logistik.de.zone
sharpmail-cli dns muster-logistik.de --live
curl -fsS -X PATCH "https://mail.firma.de/api/admin/cli/objects/Domain/muster-logistik.de" \
  -H "Authorization: Bearer smk_..." \
  -H "Content-Type: application/json" \
  -d '{"dkimSigningMode":"Dual","retentionLockMode":"Compliance","retentionDays":3650}'
using var res = await http.PatchAsJsonAsync(
    "/api/admin/cli/objects/Domain/muster-logistik.de",
    new { dkimSigningMode = "Dual", quotaGb = 200 });
res.EnsureSuccessStatusCode();
Sammlungs-Objekt (CRUD)

Account (Account/User & Account/List)

Schlüssel: email RBAC: TenantAdmin+
18 Felder

Repräsentiert ein Benutzerpostfach (@type="User", inkl. IMAP/JMAP/CalDAV/CardDAV/ActiveSync) oder eine Verteilerliste (@type="List" mit members[]).

GET /api/admin/cli/objects/Account?filter=role=TenantAdmin Listet/filtert Konten und Verteilerlisten
POST /api/admin/cli/objects/Account/User Erstellt ein neues Benutzerpostfach inkl. Standard-IMAP-Ordnern
POST /api/admin/cli/objects/Account/List Erstellt eine neue Verteilerliste mit members[]
PATCH /api/admin/cli/objects/Account/{email} Aktualisiert Quota, Weiterleitung, Abwesenheit oder Passwort
DELETE /api/admin/cli/objects/Account/{email} Deaktiviert/Soft-Deleted ein Konto revisionssicher
{ } Objekt-Schema & typisierte Felder application/json · camelCase
├─ id guid READ-ONLY
Standard: UUIDv7
Interne Principal-UUID.
├─ @type string OPTIONAL
Standard: User
Kontovariante: Benutzerpostfach (User) oder Verteilerliste (List).
Enum:"User""List"
├─ email string PRIMÄRSCHLÜSSEL
Primäre E-Mail-Adresse des Postfachs bzw. der Verteilerliste.
├─ displayName string OPTIONAL
Standard: Lokalteil
Anzeigename in Webmail, Adressbuch und ausgehenden From-Headern.
├─ password string WRITE-ONLY (SECRET)
Klartext-Passwort beim Anlegen/Ändern (wird sofort per Argon2id gehasht gespeichert).
├─ role string OPTIONAL
Standard: User
Administrative RBAC-Berechtigungsrolle.
Enum:"User""ComplianceAuditor""TenantAdmin""ServerAdmin"
├─ isActive boolean OPTIONAL
Standard: true
Konto aktivieren oder Anmeldung/Empfang sperren.
├─ quotaMb integer OPTIONAL
Standard: 5120
Postfach-Speicherlimit in MiB (5120 = 5 GiB).
├─ usedBytes long READ-ONLY
Standard: 0
Aktuell belegter Postfach-Speicher in Bytes.
├─ outboundDailyLimit integer OPTIONAL
Standard: 500
Maximale ausgehende E-Mails pro Tag für dieses Konto.
├─ forwardAddress string OPTIONAL
Optionale SRS-sichere Weiterleitungs-Zieladresse.
├─ forwardKeepOriginal boolean OPTIONAL
Standard: true
Lokale Kopie im Posteingang trotz Weiterleitung behalten.
├─ vacationEnabled boolean OPTIONAL
Standard: false
Automatische Abwesenheitsnotiz (Out-of-Office) aktivieren.
├─ vacationSubject string OPTIONAL
Betreff der automatischen Abwesenheitsantwort.
├─ vacationBody string WRITE-ONLY (SECRET)
Textkörper der Abwesenheitsantwort.
├─ twoFactorEnabled boolean READ-ONLY
Standard: false
Gibt an, ob TOTP-2FA für dieses Konto aktiv ist.
├─ members string[] OPTIONAL
Standard: []
Mitglieder-E-Mail-Adressen (nur bei @type="List").
├─ createdAtUtc datetime READ-ONLY
Erstellungszeitpunkt (UTC).
{
  "@type": "User",
  "email": "anna.weber@muster-logistik.de",
  "displayName": "Anna Weber (IT-Leitung)",
  "password": "SicheresStartPasswort!2026",
  "role": "TenantAdmin",
  "isActive": true,
  "quotaMb": 15360,
  "outboundDailyLimit": 1000,
  "forwardAddress": null,
  "forwardKeepOriginal": true,
  "vacationEnabled": false,
  "vacationSubject": "Abwesenheitsnotiz: Anna Weber",
  "vacationBody": "Ich bin ab Montag wieder erreichbar."
}
# Benutzerpostfach (15 GiB Quota) anlegen:
sharpmail-cli create Account/User \
  --set email=anna.weber@muster-logistik.de \
  --set displayName="Anna Weber" \
  --set password="SicheresStartPasswort!2026" \
  --set quotaMb=15360

# Verteilerliste anlegen:
sharpmail-cli create Account/List \
  --set email=team@muster-logistik.de \
  --set displayName="Disposition & Einkauf" \
  --set members=anna.weber@muster-logistik.de,dispo@muster-logistik.de
curl -fsS -X POST "https://mail.firma.de/api/admin/cli/objects/Account/User" \
  -H "Authorization: Bearer smk_..." \
  -H "Content-Type: application/json" \
  -d '{"email":"anna.weber@muster-logistik.de","displayName":"Anna Weber","password":"SicheresStartPasswort!2026","quotaMb":15360}'
await http.PostAsJsonAsync("/api/admin/cli/objects/Account/User", new
{
    email = "anna.weber@muster-logistik.de",
    displayName = "Anna Weber",
    password = "SicheresStartPasswort!2026",
    quotaMb = 15360
});
Sammlungs-Objekt (CRUD)

Alias

Schlüssel: address RBAC: TenantAdmin+
7 Felder

Zusätzliche E-Mail-Alias-Adresse oder Datenschutz-Masked-Email-Alias, der auf ein primäres Account-Postfach oder eine Liste zeigt.

GET /api/admin/cli/objects/Alias Listet alle Aliase und Masked-Emails
POST /api/admin/cli/objects/Alias Legt einen neuen Alias für ein Ziel-Postfach an
PATCH /api/admin/cli/objects/Alias/{address} Pausiert/aktiviert einen Alias oder ändert das Ziel-Postfach
DELETE /api/admin/cli/objects/Alias/{address} Löscht den Alias
{ } Objekt-Schema & typisierte Felder application/json · camelCase
├─ address string PRIMÄRSCHLÜSSEL
Die Alias-E-Mail-Adresse (z. B. "rechnung@firma.de" oder "shop-8f2k@firma.de").
├─ target string PFLICHTFELD
Primäre E-Mail-Adresse des Ziel-Postfachs.
├─ principalId guid READ-ONLY
Aufgelöste UUID des Ziel-Postfachs.
├─ description string OPTIONAL
Standard: ""
Verwendungszweck oder Shop-/Dienstname (wird auch im Webmail-Composer angezeigt).
├─ isMasked boolean OPTIONAL
Standard: false
Kennzeichnet die Adresse als abschaltbare Masked-Email-Adresse.
├─ isEnabled boolean OPTIONAL
Standard: true
Wenn false, werden eingehende Mails an diesen Alias abgewiesen, ohne die Adresse freizugeben.
├─ createdAtUtc datetime READ-ONLY
Erstellungszeitpunkt (UTC).
{
  "address": "shop-8f2k@muster-logistik.de",
  "target": "anna.weber@muster-logistik.de",
  "description": "Fachbuchhandlung / Online-Bestellung",
  "isMasked": true,
  "isEnabled": true
}
# Masked-Email-Alias anlegen:
sharpmail-cli create Alias \
  --set address=shop-8f2k@muster-logistik.de \
  --set target=anna.weber@muster-logistik.de \
  --set description="Fachbuchhandlung" \
  --set isMasked=true

# Alias bei Spam-Aufkommen mit 1 Befehl stummschalten:
sharpmail-cli update Alias shop-8f2k@muster-logistik.de --set isEnabled=false
curl -fsS -X POST "https://mail.firma.de/api/admin/cli/objects/Alias" \
  -H "Authorization: Bearer smk_..." \
  -H "Content-Type: application/json" \
  -d '{"address":"vertrieb@muster-logistik.de","target":"anna.weber@muster-logistik.de","description":"Vertrieb & Angebote"}'
await http.PostAsJsonAsync("/api/admin/cli/objects/Alias", new
{
    address = "vertrieb@muster-logistik.de",
    target = "anna.weber@muster-logistik.de",
    description = "Vertrieb & Angebote",
    isEnabled = true
});
Sammlungs-Objekt (CRUD)

ApiKey

Schlüssel: id RBAC: TenantAdmin+
11 Felder

Unveränderbarer (immutable), rollen- und CIDR-beschränkter Scoped API-Schlüssel (smk_<id>_<secret>) für /api/v1/send, SCIM 2.0 oder sharpmail-cli.

GET /api/admin/cli/objects/ApiKey Listet alle aktiven API-Keys (ohne geheimes Token)
POST /api/admin/cli/objects/ApiKey Erstellt neuen API-Key und gibt apiKey (smk_...) einmalig zurück
DELETE /api/admin/cli/objects/ApiKey/{id} Widerruft den API-Key sofort
{ } Objekt-Schema & typisierte Felder application/json · camelCase
├─ id guid READ-ONLY
Standard: UUIDv7
Eindeutige Schlüssel-UUID (zum Widerrufen per DELETE).
├─ apiKey string CREATE-ONLY
Standard: smk_<id>_<secret>
Vollständiges Bearer-Token. Wird aus Sicherheitsgründen NUR einmalig bei POST / create zurückgegeben!
├─ label string PFLICHTFELD
Sprechende Bezeichnung (z. B. "Ansible GitOps" oder "Shopware 6 Versand").
├─ role string OPTIONAL
Standard: TenantAdmin
Berechtigungsumfang (User darf ausschließlich POST /api/v1/send aufrufen).
Enum:"User""ComplianceAuditor""TenantAdmin""ServerAdmin"
├─ senderAddress string OPTIONAL
Erlaubte Absenderadresse (Pflichtfeld bei role="User").
├─ defaultCategory string OPTIONAL
Standard: transactional
Standard-Versandkategorie für diesen Schlüssel.
Enum:"critical""transactional""notification""marketing"
├─ allowedCidrs string[] OPTIONAL
Standard: [] (Alle IPs)
Erlaubte Quell-IPv4/IPv6-Netze in CIDR-Notation (z. B. ["10.20.0.0/16", "198.51.100.12/32"]).
├─ expiresInDays integer WRITE-ONLY (SECRET)
Standard: null (Kein Ablauf)
Automatische Gültigkeitsdauer in Tagen ab Erstellung.
├─ expiresAtUtc datetime READ-ONLY
Berechnetes Ablaufdatum in UTC.
├─ outboundDailyLimit integer OPTIONAL
Standard: 10000
Maximal erlaubte E-Mails pro Tag über diesen API-Key.
├─ isActive boolean READ-ONLY
Standard: true
Status des Schlüssels.
{
  "label": "Shopware 6 ERP Rechnungsversand",
  "role": "User",
  "senderAddress": "rechnung@muster-logistik.de",
  "defaultCategory": "transactional",
  "allowedCidrs": ["10.20.10.15/32", "2a01:4f8:120:44aa::/64"],
  "expiresInDays": 180,
  "outboundDailyLimit": 10000
}
# CIDR-geschützten Key für Ansible / sharpmail-cli erstellen:
sharpmail-cli create ApiKey \
  --set label="GitLab CI / Ansible" \
  --set role=TenantAdmin \
  --set allowedCidrs=10.20.0.0/16 \
  --set expiresInDays=90

# Schlüssel widerrufen:
sharpmail-cli delete ApiKey 0195f2a0-8b14-7000-9a10-001122334455
curl -fsS -X POST "https://mail.firma.de/api/admin/cli/objects/ApiKey" \
  -H "Authorization: Bearer smk_..." \
  -H "Content-Type: application/json" \
  -d '{"label":"Shopware 6","role":"User","senderAddress":"rechnung@muster-logistik.de","allowedCidrs":["10.20.10.15/32"],"expiresInDays":180}'
var res = await http.PostAsJsonAsync("/api/admin/cli/objects/ApiKey", new
{
    label = "Shopware 6",
    role = "User",
    senderAddress = "rechnung@muster-logistik.de",
    allowedCidrs = new[] { "10.20.10.15/32" },
    expiresInDays = 180
});
var created = await res.Content.ReadFromJsonAsync<JsonElement>();
string oneTimeSecretKey = created.GetProperty("apiKey").GetString()!;
Sammlungs-Objekt (CRUD)

Route

Schlüssel: domain RBAC: ServerAdmin+
10 Felder

Domänenspezifische ausgehende SMTP-Route oder TLS-Zertifikatsausnahme (z. B. StartTlsIgnoreCert bei Partner-MX mit Zertifikats-Mismatch oder dedizierter Relay-Connector).

GET /api/admin/cli/objects/Route Listet alle ausgehenden Sonderrouten
POST /api/admin/cli/objects/Route Legt eine neue Domain-Route oder TLS-Ausnahme an
PATCH /api/admin/cli/objects/Route/{domain} Aktualisiert Ziel-Host, Port oder TLS-Modus
DELETE /api/admin/cli/objects/Route/{domain} Entfernt die Sonderroute
{ } Objekt-Schema & typisierte Felder application/json · camelCase
├─ domain string PRIMÄRSCHLÜSSEL
Ziel-Empfängerdomain (z. B. "neff.me" oder "*.partner-holding.eu").
├─ targetHost string OPTIONAL
Standard: "" (Auto DNS-MX)
Ziel-Relay-Hostname oder IP. Leer lassen, damit SharpMailserver den MX-Eintrag automatisch per DNS auflöst!
├─ targetPort integer OPTIONAL
Standard: 25
Ziel-TCP-Port (25 für MX, 587 für STARTTLS-Relay, 465 für Implicit-TLS).
├─ tlsMode string OPTIONAL
Standard: StartTlsOptional
TLS- und Zertifikatsprüfungs-Modus für diese Ziel-Domain.
Enum:"StartTlsOptional""StartTlsRequired""StartTlsIgnoreCert""ImplicitTls""ImplicitTlsIgnoreCert""None"
├─ username string OPTIONAL
Optionaler SMTP-AUTH-Benutzername für Smart-Host-Relays.
├─ password string WRITE-ONLY (SECRET)
Optionales SMTP-AUTH-Passwort (wird verschlüsselt gespeichert).
├─ hasPassword boolean READ-ONLY
Standard: false
Zeigt an, ob ein Passwort hinterlegt ist.
├─ clearPassword boolean WRITE-ONLY (SECRET)
Standard: false
Auf true setzen, um ein gespeichertes Passwort zu löschen.
├─ description string OPTIONAL
Dokumentations-Notiz für Administratoren.
├─ enabled boolean OPTIONAL
Standard: true
Route aktivieren oder temporär deaktivieren.
{
  "domain": "neff.me",
  "targetHost": "",
  "targetPort": 25,
  "tlsMode": "StartTlsIgnoreCert",
  "username": null,
  "description": "Shared-Hosting-MX mit abweichendem Zertifikatsnamen (Auto DNS-MX)",
  "enabled": true
}
# Partner-Domain mit fehlerhaftem MX-Zertifikat per Auto-DNS-MX freigeben:
sharpmail-cli create Route \
  --set domain=neff.me \
  --set tlsMode=StartTlsIgnoreCert \
  --set description="TLS NameMismatch auf Partner-MX erlauben"

# Internes ERP-Subnetz an lokalen Connector routen:
sharpmail-cli create Route \
  --set domain=erp.firma.intern \
  --set targetHost=10.40.2.15 \
  --set targetPort=25
curl -fsS -X POST "https://mail.firma.de/api/admin/cli/objects/Route" \
  -H "Authorization: Bearer smk_..." \
  -H "Content-Type: application/json" \
  -d '{"domain":"neff.me","targetHost":"","targetPort":25,"tlsMode":"StartTlsIgnoreCert","enabled":true}'
await http.PostAsJsonAsync("/api/admin/cli/objects/Route", new
{
    domain = "neff.me",
    targetHost = "",
    targetPort = 25,
    tlsMode = "StartTlsIgnoreCert",
    enabled = true
});
Singleton-Policy

TransactionalSend (Singleton)

Schlüssel: singleton RBAC: TenantAdmin+
11 Felder

Steuert progressives 28-Tage-IP-Warming, E-Mail-Kategorien (critical, transactional, notification, marketing) und getrennte Stunden-/Tageslimits pro Empfänger-Provider (Google, Microsoft, Yahoo/AOL, T-Online/GMX/WEB.DE, iCloud, *).

GET /api/admin/cli/objects/TransactionalSend/singleton Liest aktive IP-Warming- & Provider-Quota-Policy
PATCH /api/admin/cli/objects/TransactionalSend/singleton Aktualisiert Warming-Tag, Preset oder Provider-Quotas
{ } Objekt-Schema & typisierte Felder application/json · camelCase
├─ enabled boolean OPTIONAL
Standard: true
Aktiviert die kategorie- und providerbasierte Kontingentsteuerung.
├─ warmingEnabled boolean OPTIONAL
Standard: false
Aktiviert die tägliche IP-Warming-Prozentrampe.
├─ startAtWarmingDay integer WRITE-ONLY (SECRET)
Standard: 1
Setzt den aktuellen Warming-Tag gezielt auf Tag 1..365.
├─ currentWarmingDay integer READ-ONLY
Aktueller Tag in der Warming-Kurve.
├─ currentWarmingPercent integer READ-ONLY
Aktuell freigegebener Prozentsatz der Ziel-Kontingente.
├─ warmingDailyRampPercents integer[] OPTIONAL
Standard: [5,7,10,...,100]
Prozentwerte pro Warming-Tag.
├─ maxDeferHours integer OPTIONAL
Standard: 48
Maximaler Pacing-Vorlauf in Stunden bei DeferQueue.
├─ defaultCategory string OPTIONAL
Standard: transactional
Standard-Kategorie, falls beim API-Aufruf keine angegeben wird.
Enum:"critical""transactional""notification""marketing"
├─ preset string WRITE-ONLY (SECRET)
1-Klick-Vorlage zum Laden bewährter Warming-Kurven.
Enum:"warming_28d""warming_14d""production_100"
├─ categories CategoryPolicy[] OPTIONAL
Standard: 4 Kategorien
Array aus { slug, displayName, priority, bypassWarming, shareOfProviderQuotaPercent, overflowAction }.
├─ providers ProviderQuota[] OPTIONAL
Standard: 6 Provider-Gruppen
Array aus { id, displayName, domains[], hourlyLimit, dailyLimit, categoryOverrides, enabled }.
{
  "enabled": true,
  "warmingEnabled": true,
  "startAtWarmingDay": 1,
  "maxDeferHours": 48,
  "defaultCategory": "transactional",
  "preset": "warming_28d"
}
# 28-Tage IP-Warming aktivieren:
sharpmail-cli update TransactionalSend --set preset=warming_28d

# Direkt auf Warming-Tag 14 vorspringen:
sharpmail-cli update TransactionalSend --set startAtWarmingDay=14
curl -fsS -X PATCH "https://mail.firma.de/api/admin/cli/objects/TransactionalSend/singleton" \
  -H "Authorization: Bearer smk_..." \
  -H "Content-Type: application/json" \
  -d '{"preset":"warming_28d","enabled":true}'
await http.PatchAsJsonAsync(
    "/api/admin/cli/objects/TransactionalSend/singleton",
    new { preset = "warming_28d", enabled = true });
Singleton-Policy

ReputationShield (Singleton)

Schlüssel: singleton RBAC: TenantAdmin+
20 Felder

Optionaler Outbound-Reputationsschutz: Automatische Bounce-/Complaint-Suppression-Liste, RFC 8058 One-Click-Unsubscribe, Bounce-Circuit-Breaker, adaptives 421-ISP-Backoff und HMAC-SHA256-Webhooks.

GET /api/admin/cli/objects/ReputationShield/singleton Liest aktuelle Reputation-Shield-Konfiguration
PATCH /api/admin/cli/objects/ReputationShield/singleton Aktualisiert Schutzmodule oder lädt ein Preset (off | recommended | strict_bulk)
{ } Objekt-Schema & typisierte Felder application/json · camelCase
├─ preset string WRITE-ONLY (SECRET)
Lädt ein abgestimmtes Schutzprofil mit einem Aufruf.
Enum:"off""recommended""strict_bulk"
├─ enableSuppressionPreCheck boolean OPTIONAL
Standard: false
Filtert bekannte Hard-Bounce- und Beschwerde-Adressen vor dem Versand aus.
├─ enforceSuppressionOnSmtpRelay boolean OPTIONAL
Standard: false
Prüft die Suppression-Liste auch bei authentifizierter SMTP-Einlieferung.
├─ allSuppressedBehavior string OPTIONAL
Standard: reject_422
Antwortverhalten, wenn alle Empfänger unterdrückt sind.
Enum:"reject_422""accept_noop"
├─ autoSuppressHardBounces boolean OPTIONAL
Standard: false
Nimmt permanente 5xx-Hard-Bounces automatisch in die Suppression-Liste auf.
├─ hardBounceSuppressionDays integer OPTIONAL
Standard: 180
Speicherdauer für Hard-Bounces in Tagen.
├─ autoSuppressConsecutiveSoftBounces boolean OPTIONAL
Standard: false
Unterdrückt Empfänger nach wiederholten 4xx-Soft-Bounces.
├─ softBounceEscalationThreshold integer OPTIONAL
Standard: 5
Anzahl aufeinanderfolgender Soft-Bounces bis zur Aufnahme.
├─ autoSuppressFblComplaints boolean OPTIONAL
Standard: false
Wertet eingehende RFC-5965-ARF-Missbrauchsmeldungen automatisch aus.
├─ enableOneClickUnsubscribe boolean OPTIONAL
Standard: false
Fügt DKIM-signierte RFC-8058 List-Unsubscribe-Header ein.
├─ oneClickUnsubscribeCategories string[] OPTIONAL
Standard: ["marketing","notification"]
Kategorien, die einen One-Click-Unsubscribe-Header erhalten.
├─ enableBounceCircuitBreaker boolean OPTIONAL
Standard: false
Pausiert nicht-kritischen Massenversand bei überhöhter Bounce-/Beschwerdequote.
├─ maxHardBouncePercent number OPTIONAL
Standard: 5.0
Schwellenwert für 24h-Hard-Bounce-Quote in Prozent.
├─ maxComplaintPercent number OPTIONAL
Standard: 0.1
Schwellenwert für 24h-Spam-Beschwerdequote in Prozent.
├─ allowCriticalWhenTripped boolean OPTIONAL
Standard: true
Lässt kritische 2FA-/Systemmails auch bei ausgelöstem Circuit-Breaker durch.
├─ enableAdaptiveIspBackoff boolean OPTIONAL
Standard: false
Automatische Abkühlphase nach 421/451-Drosselungen durch Ziel-ISPs.
├─ ispCooldownMinutes integer OPTIONAL
Standard: 15
Dauer der ISP-Abkühlphase in Minuten.
├─ webhookEnabled boolean OPTIONAL
Standard: false
Sendet HMAC-SHA256-signierte Webhooks bei Bounces und Abmeldungen.
├─ webhookUrl string OPTIONAL
HTTPS-Ziel-URL für Event-Webhooks.
├─ webhookSecret string WRITE-ONLY (SECRET)
Geheimer Schlüssel für den Header X-SharpMail-Signature.
{
  "preset": "recommended",
  "enableSuppressionPreCheck": true,
  "autoSuppressHardBounces": true,
  "hardBounceSuppressionDays": 180,
  "enableOneClickUnsubscribe": true,
  "oneClickUnsubscribeCategories": ["marketing", "notification"],
  "enableBounceCircuitBreaker": true,
  "maxHardBouncePercent": 5.0,
  "maxComplaintPercent": 0.1,
  "allowCriticalWhenTripped": true,
  "enableAdaptiveIspBackoff": true,
  "webhookEnabled": true,
  "webhookUrl": "https://erp.firma.de/webhooks/sharpmail"
}
# Empfohlenen Reputationsschutz aktivieren:
sharpmail-cli update ReputationShield --set preset=recommended

# Webhook-Ziel konfigurieren:
sharpmail-cli update ReputationShield \
  --set webhookEnabled=true \
  --set webhookUrl=https://erp.firma.de/webhooks/sharpmail \
  --set webhookSecret=whsec_9f8e7d6c5b4a
curl -fsS -X PATCH "https://mail.firma.de/api/admin/cli/objects/ReputationShield/singleton" \
  -H "Authorization: Bearer smk_..." \
  -H "Content-Type: application/json" \
  -d '{"preset":"recommended"}'
await http.PatchAsJsonAsync(
    "/api/admin/cli/objects/ReputationShield/singleton",
    new { preset = "recommended" });
Singleton-Policy

SpamGuard (Singleton)

Schlüssel: singleton RBAC: ServerAdmin+
15 Felder

Mehrstufige Inbound-Abwehr: SPF/DKIM/DMARC/ARC-Prüfung, Smart Greylisting (/24 IPv4 & /64 IPv6), Online-ML-Klassifikator (FTRL-Proximal), DNSBL-Zonen, Allow-/Blocklisten und nativer ClamAV-TCP-Scan.

GET /api/admin/cli/objects/SpamGuard/singleton Liest aktuelle SpamGuard-Schwellenwerte & Trainingszähler
PATCH /api/admin/cli/objects/SpamGuard/singleton Aktualisiert Scores, DNSBLs, Allowlists oder ClamAV im laufenden Betrieb
{ } Objekt-Schema & typisierte Felder application/json · camelCase
├─ enableEmailAuthChecks boolean OPTIONAL
Standard: true
Prüft SPF, DKIM, DMARC und ARC bei eingehenden E-Mails.
├─ enableGreylisting boolean OPTIONAL
Standard: true
Adaptives Smart Greylisting für unbekannte Erstsender.
├─ greylistRetryDelaySeconds integer OPTIONAL
Standard: 240
Wartezeit in Sekunden beim ersten Zustellversuch (Standard: 240s).
├─ junkScoreThreshold number OPTIONAL
Standard: 4.5
Ab diesem Score wird die E-Mail in den Junk-Ordner zugestellt.
├─ rejectScoreThreshold number OPTIONAL
Standard: 9.0
Ab diesem Score wird die E-Mail direkt im SMTP-Dialog mit 550 abgewiesen.
├─ tagSubjectOnJunk boolean OPTIONAL
Standard: false
Optionales Präfix im Betreff von Junk-Nachrichten.
├─ subjectTagPrefix string OPTIONAL
Standard: "[SPAM] "
Präfix-Text bei aktiviertem tagSubjectOnJunk.
├─ enableStructuralHeuristics boolean OPTIONAL
Standard: true
Prüft MIME-Struktur, HTML-Obfuskierung und Phishing-Merkmale.
├─ dnsblZones string[] OPTIONAL
Standard: ["bl.spamcop.net","ix.dnsbl.manitu.net"]
Abgefragte Echtzeit-Blocklisten (DNSBL).
├─ dnsblHitScore number OPTIONAL
Standard: 3.5
Score-Aufschlag pro DNSBL-Treffer.
├─ allowedSendersOrDomains string[] OPTIONAL
Standard: []
Explizite Allowlist für vertrauenswürdige Absender oder Domains.
├─ blockedSendersOrDomains string[] OPTIONAL
Standard: []
Explizite Blocklist für gesperrte Absender oder Domains.
├─ clamAvEnabled boolean OPTIONAL
Standard: false
Aktiviert den Virenscan über den ClamAV-Daemon (INSTREAM).
├─ clamAvHost string OPTIONAL
Standard: "127.0.0.1"
Hostname oder IP des ClamAV-Dienstes.
├─ clamAvPort integer OPTIONAL
Standard: 3310
TCP-Port des ClamAV-Dienstes.
{
  "enableEmailAuthChecks": true,
  "enableGreylisting": true,
  "greylistRetryDelaySeconds": 240,
  "junkScoreThreshold": 4.5,
  "rejectScoreThreshold": 9.0,
  "enableStructuralHeuristics": true,
  "dnsblZones": ["bl.spamcop.net", "ix.dnsbl.manitu.net"],
  "dnsblHitScore": 3.5,
  "allowedSendersOrDomains": ["datev.de", "partner-spedition.de"],
  "blockedSendersOrDomains": [],
  "clamAvEnabled": false,
  "clamAvHost": "127.0.0.1",
  "clamAvPort": 3310
}
# Partner-Domains auf die Allowlist setzen:
sharpmail-cli update SpamGuard \
  --set allowedSendersOrDomains=datev.de,partner-spedition.de

# Schwellenwerte anpassen:
sharpmail-cli update SpamGuard --set junkScoreThreshold=4.5 --set rejectScoreThreshold=9.0
curl -fsS -X PATCH "https://mail.firma.de/api/admin/cli/objects/SpamGuard/singleton" \
  -H "Authorization: Bearer smk_..." \
  -H "Content-Type: application/json" \
  -d '{"junkScoreThreshold":4.5,"rejectScoreThreshold":9.0,"allowedSendersOrDomains":["datev.de"]}'
await http.PatchAsJsonAsync(
    "/api/admin/cli/objects/SpamGuard/singleton",
    new { junkScoreThreshold = 4.5, rejectScoreThreshold = 9.0 });
Singleton-Policy

SmtpQueue (Singleton)

Schlüssel: singleton RBAC: ServerAdmin+
19 Felder

Steuert die ausgehende MX-Zustell-Queue, Worker-Parallelität, Retry-Intervalle, ISP-Throttling, ausgehende TLS-Zertifikatsprüfung, globalen Smart-Host und eingehende ESMTP-Schutzlimits.

GET /api/admin/cli/objects/SmtpQueue/singleton Liest alle Queue-, TLS- und ESMTP-Parameter
PATCH /api/admin/cli/objects/SmtpQueue/singleton Aktualisiert Queue-Worker, Retry-Zeiten oder ESMTP-Limits sofort
{ } Objekt-Schema & typisierte Felder application/json · camelCase
├─ outboundQueuePaused boolean OPTIONAL
Standard: false
Pausiert die gesamte ausgehende Zustellung (Mails werden weiter eingereiht).
├─ outboundWorkerConcurrency integer OPTIONAL
Standard: 8
Anzahl paralleler Outbound-Zustell-Worker.
├─ maxDeliveryAttempts integer OPTIONAL
Standard: 10
Maximale Zustellversuche vor endgültigem Bounce (NDN).
├─ retryScheduleMinutes integer[] OPTIONAL
Standard: [5,15,60,240,720]
Wartezeiten in Minuten zwischen Zustellversuchen.
├─ maxConcurrentConnectionsPerMxDomain integer OPTIONAL
Standard: 4
Maximale gleichzeitige Verbindungen zu derselben Ziel-Domain.
├─ strictThrottleDomains string[] OPTIONAL
Standard: ["t-online.de","gmx.de","web.de","yahoo.com"]
Domains mit reduzierter Verbindungs-Parallelität.
├─ strictThrottleMaxConcurrency integer OPTIONAL
Standard: 2
Maximale gleichzeitige Verbindungen für strictThrottleDomains.
├─ outboundConnectTimeoutSeconds integer OPTIONAL
Standard: 30
TCP/TLS-Verbindungs-Timeout in Sekunden.
├─ outboundBindAddress string OPTIONAL
Standard: "" (Auto)
Feste lokale Quell-IPv4/IPv6-Adresse für ausgehende Verbindungen.
├─ outboundUseStartTls boolean OPTIONAL
Standard: true
STARTTLS bei ausgehenden MX-Verbindungen nutzen.
├─ requireOutboundTls boolean OPTIONAL
Standard: false
Zustellung abbrechen, wenn die Gegenstelle kein TLS unterstützt.
├─ outboundTlsCertValidation string OPTIONAL
Standard: Opportunistic
Globale X.509-Zertifikatsprüfung für Port 25 (Opportunistic gemäß RFC 7435 empfohlen).
Enum:"Opportunistic""IgnoreErrors""Strict"
├─ outboundSmartHost string OPTIONAL
Standard: ""
Optionaler globaler Upstream-Smart-Host.
├─ outboundSmartPort integer OPTIONAL
Standard: 587
TCP-Port des globalen Smart-Hosts.
├─ maxMessageSizeMb long OPTIONAL
Standard: 50
Globales ESMTP-SIZE-Limit in MiB.
├─ maxRecipientsPerTransaction integer OPTIONAL
Standard: 100
Maximale RCPT-TO-Befehle pro SMTP-Transaktion.
├─ maxConnectionsPerIp integer OPTIONAL
Standard: 20
Maximale gleichzeitige eingehende Verbindungen pro Quell-IP.
├─ tarpitDelayMs integer OPTIONAL
Standard: 1500
Künstliche Verzögerung in ms bei ungültigen Befehlen/Auth-Fehlern.
├─ requireTlsForAuth boolean OPTIONAL
Standard: true
Erlaubt SMTP-AUTH ausschließlich über verschlüsselte TLS-Verbindungen.
{
  "outboundQueuePaused": false,
  "outboundWorkerConcurrency": 8,
  "maxDeliveryAttempts": 10,
  "retryScheduleMinutes": [5, 15, 60, 240, 720],
  "maxConcurrentConnectionsPerMxDomain": 4,
  "strictThrottleDomains": ["t-online.de", "gmx.de", "web.de", "yahoo.com"],
  "strictThrottleMaxConcurrency": 2,
  "outboundUseStartTls": true,
  "requireOutboundTls": false,
  "outboundTlsCertValidation": "Opportunistic",
  "maxMessageSizeMb": 50,
  "maxRecipientsPerTransaction": 100,
  "tarpitDelayMs": 1500,
  "requireTlsForAuth": true
}
# Outbound-TLS auf Opportunistic (RFC 7435) setzen & MaxMessageSize auf 75 MiB erhöhen:
sharpmail-cli update SmtpQueue \
  --set outboundTlsCertValidation=Opportunistic \
  --set maxMessageSizeMb=75
curl -fsS -X PATCH "https://mail.firma.de/api/admin/cli/objects/SmtpQueue/singleton" \
  -H "Authorization: Bearer smk_..." \
  -H "Content-Type: application/json" \
  -d '{"outboundTlsCertValidation":"Opportunistic","maxMessageSizeMb":75}'
await http.PatchAsJsonAsync(
    "/api/admin/cli/objects/SmtpQueue/singleton",
    new { outboundTlsCertValidation = "Opportunistic", maxMessageSizeMb = 75 });
Singleton-Policy

TransportRules & Server (Singletons)

Schlüssel: singleton RBAC: ServerAdmin+
11 Felder

Unternehmensweite Pflicht-Signatur (HGB/GmbHG-Disclaimer vor DKIM-Signatur), globales System-Sieve-Skript, Fail2Ban-Auto-Ban sowie Server-Hostname & Status.

GET /api/admin/cli/objects/TransportRules/singleton Liest Pflicht-Signatur, System-Sieve & Auto-Ban
PATCH /api/admin/cli/objects/TransportRules/singleton Aktualisiert Transportregeln sofort
GET /api/admin/cli/objects/Server/singleton Liest ServerHostName, Datenbank-Engine, Queue-Stand & Lizenzstatus
PATCH /api/admin/cli/objects/Server/singleton Ändert den kanonischen ServerHostName im laufenden Betrieb
{ } Objekt-Schema & typisierte Felder application/json · camelCase
├─ outboundDisclaimerEnabled boolean OPTIONAL
Standard: false
Fügt ausgehenden E-Mails automatisch das Unternehmens-Impressum an.
├─ outboundDisclaimerExternalOnly boolean OPTIONAL
Standard: true
Signatur nur bei externen Empfängern anfügen.
├─ outboundDisclaimerText string OPTIONAL
Standard: ""
Reintext-Fassung des Disclaimers.
├─ outboundDisclaimerHtml string OPTIONAL
Standard: ""
HTML-Fassung des Disclaimers.
├─ inboundSystemSieve string OPTIONAL
Standard: ""
Globales RFC-5228-Sieve-Skript, das vor allen Benutzerregeln ausgeführt wird.
├─ autoBanThreshold integer OPTIONAL
Standard: 8
Anzahl fehlgeschlagener Logins bis zur automatischen IP-Sperre.
├─ autoBanDurationMinutes integer OPTIONAL
Standard: 30
Sperrdauer der IP-Adresse in Minuten.
├─ serverHostName string OPTIONAL
Standard: mail.<domain>
Kanonischer EHLO-, TLS- und Autodiscover-Hostname (Objekt: Server).
├─ storageProvider string READ-ONLY
Standard: Sqlite | SqlServer | Postgres
Aktive Datenbank-Engine (Objekt: Server).
├─ activeQueueCount integer READ-ONLY
Standard: 0
Aktuelle Anzahl Nachrichten in der Outbound-Queue (Objekt: Server).
├─ licenseState string READ-ONLY
Standard: EnterpriseActive
Lizenzstatus der Instanz (Objekt: Server).
{
  "outboundDisclaimerEnabled": true,
  "outboundDisclaimerExternalOnly": true,
  "outboundDisclaimerText": "-- \nMuster Logistik GmbH · Industriestraße 18 · 70565 Stuttgart · HRB 774819",
  "outboundDisclaimerHtml": "<p style='font-size:11px;color:#64748b'><strong>Muster Logistik GmbH</strong> &middot; 70565 Stuttgart &middot; HRB 774819</p>",
  "inboundSystemSieve": "require [\"fileinto\"];\nif header :contains \"X-Spam-Flag\" \"YES\" { fileinto \"Junk\"; }",
  "autoBanThreshold": 8,
  "autoBanDurationMinutes": 30
}
# Pflicht-Impressum & Auto-Ban aktualisieren:
sharpmail-cli update TransportRules \
  --set outboundDisclaimerEnabled=true \
  --set autoBanThreshold=8

# Kanonischen Server-Hostnamen abfragen oder setzen:
sharpmail-cli get Server
sharpmail-cli update Server --set serverHostName=mail.muster-logistik.de
curl -fsS -X GET "https://mail.firma.de/api/admin/cli/objects/Server/singleton" \
  -H "Authorization: Bearer smk_..."
var status = await http.GetFromJsonAsync<JsonElement>("/api/admin/cli/objects/Server/singleton");
Console.WriteLine($"Host: {status.GetProperty("serverHostName")}, Queue: {status.GetProperty("activeQueueCount")}");