{
  "openapi": "3.0.3",
  "info": {
    "title": "Mailpro™ Email API v2",
    "version": "2",
    "description": "Die Mailpro™ Email API v2 ermöglicht Ihnen die programmatische Verwaltung von Kontaktlisten, E-Mail-Vorlagen,\nAbsenderadressen und Kampagnen — sowie den Versand von Massen- und Transaktions-E-Mails.\n\n## Authentifizierung\n\nJeder Endpunkt akzeptiert **drei Authentifizierungsmethoden**. Verwenden Sie diejenige, die zu Ihrem\nStack passt.\n\n- **OAuth 2.0** — Tokens mit Scopes, widerrufbar, für Drittanbieter-Apps und\n  Integrationsplattformen (Zapier, Make, n8n). Die einzige Methode, die Sie an\n  Dritte weitergeben können. **OAuth-Tokens werden pro Endpunkt anhand ihrer Scopes geprüft** (siehe unten).\n- **Bearer JWT** (Legacy) — ein HMAC-Token von `POST /token`, ohne Scopes.\n- **IdClient + ApiKey** (Legacy) — Client-ID + API-Schlüssel.\n\n> Der Legacy-Bearer-JWT und IdClient+ApiKey funktionieren unverändert weiter und unterliegen **keiner**\n> Scope-Prüfung. Nur OAuth-2.0-Zugriffstokens unterliegen den Scope-Prüfungen pro Endpunkt,\n> die bei jeder Operation unten angegeben sind.\n\n### Methode 1 — OAuth 2.0 (empfohlen für Integrationen)\n\nMailpro betreibt **einen einzigen** OAuth-2.0-Autorisierungsserver für alle seine APIs, unter einer\neinheitlichen, versionsunabhängigen Adresse: **`https://api.mailpro.com/oauth/`**. Es gibt\nkeinen OAuth-Endpunkt pro Version — Sie erhalten ein Token über `/oauth/token`, und\n**dasselbe** Token funktioniert mit dieser Email API v2, mit CRM v3 und mit SMS. Welche\nEndpunkte es aufrufen darf, bestimmen die **Scopes** des Tokens, nicht die Basis-URL\nder API. Aussteller (`iss`-Claim): `https://api.mailpro.com/oauth/`.\n\n| Endpunkt | URL |\n|----------|-----|\n| Autorisierung | `GET https://api.mailpro.com/oauth/authorize` |\n| Token / Erneuerung | `POST https://api.mailpro.com/oauth/token` |\n| JWKS | `GET https://api.mailpro.com/oauth/.well-known/jwks` |\n| Discovery | `GET https://api.mailpro.com/oauth/.well-known/openid-configuration` |\n\nGrants: `authorization_code` **+ PKCE (S256, obligatorisch)**, `client_credentials`,\n`refresh_token` (Rotation). Gültigkeit des Zugriffstokens: **20 Min.**; Refresh-Token: **30 Tage**\n(gleitend, einmalig verwendbar); Autorisierungscode: **60 s**.\n\n**Schnellstart — Token abrufen und diese API aufrufen** (Platzhalter ersetzen; committen Sie\nniemals ein echtes Secret):\n\n```bash\ncurl -X POST https://api.mailpro.com/oauth/token \\\n  -H \"Content-Type: application/x-www-form-urlencoded\" \\\n  -d \"grant_type=client_credentials\" \\\n  -d \"client_id=YOUR_CLIENT_ID\" \\\n  -d \"client_secret=YOUR_CLIENT_SECRET\" \\\n  -d \"scope=email:send email:read\"\n```\n\nRufen Sie anschließend diese API mit `Authorization: Bearer ACCESS_TOKEN` auf. Dasselbe Token\nfunktioniert mit den APIs CRM v3 und SMS. Ein Token, dem der für einen Endpunkt erforderliche\nScope fehlt, erhält **403 `insufficient_scope`**. Vollständiger Ablauf und Scope-Katalog:\nsiehe die Dokumentation der **CRM v3** API › Authentifizierung. Für E-Mail relevante Scopes:\n`email:send`, `email:read`, `email:templates:read`, `email:templates:write`,\n`contacts:read`, `contacts:write`, `account:read`.\n\n### Methode 2 — Bearer JWT (Legacy)\n\n```\nAuthorization: Bearer <access_token>\n```\n\nSie erhalten ein Token über `POST /token` (form-kodiert, OAuth2 Password Grant):\n\n```\nPOST https://api.mailpro.com/v2/token\nContent-Type: application/x-www-form-urlencoded\n\ngrant_type=password&username=YOUR_USERNAME&password=YOUR_API_KEY\n```\n\nDasselbe Token ist auch für die CRM API v3 und die SMS API gültig —\neinmal authentifizieren, jede API aufrufen. Tokens sind standardmäßig **30 Tage** lang gültig;\nverwenden Sie `grant_type=refresh_token`, um sie ohne erneute Authentifizierung zu erneuern. Ohne Scopes\n— bevorzugen Sie OAuth 2.0 für installierbare Integrationen.\n\n### Methode 3 — IdClient + ApiKey\n\nZwei Zugangsdaten:\n\n| Parameter  | Typ     | Beschreibung |\n|------------|---------|-------------|\n| `IdClient` | integer | Ihre numerische Mailpro-Kundennummer, zu finden unter **Einstellungen → API-Zugang** |\n| `ApiKey`   | string  | Ihr API-Schlüssel, zu finden unter **Einstellungen → API-Zugang** |\n\nSenden Sie sie an einer der folgenden Stellen — wählen Sie eine aus:\n\n1. **HTTP-Header (empfohlen)** — `IdClient: 12345` und `ApiKey: a1b2c3d4-…`.\n   URLs werden von Webservern, CDNs und Proxys protokolliert, sodass ein Schlüssel im Query-String\n   in Zugriffsprotokollen offengelegt werden kann. Header werden nicht protokolliert.\n2. **Query-String (Legacy, weiterhin funktionsfähig)** — `?IdClient=12345&ApiKey=…`.\n   Beibehalten zur Abwärtskompatibilität mit bestehenden Integrationen. Wechseln Sie so bald wie\n   möglich zu Headern.\n3. **Form-Body (nur POST)** — `IdClient=12345&ApiKey=…` in\n   `application/x-www-form-urlencoded`.\n\nWenn Sie Zugangsdaten an mehreren Stellen angeben, **gewinnt der Header**.\n\n### OAuth-Scope-Prüfung pro Endpunkt (Email v2)\n\nFür per OAuth ausgestellte Tokens verlangt jede Endpunktgruppe einen Scope (die Legacy-Authentifizierung\nist davon ausgenommen). Jede Operation nennt ihren Scope unter **Authorization**. Übersicht:\n\n| Endpunkte | Erforderlicher Scope |\n|-----------|----------------------|\n| `/send/*` (Kampagnen, Transaktional, Planung, Test — außer `/send/{IdSend}/status`) | `email:send` |\n| `/stats/*` (außer `/stats/del`), `/history/list`, `/send/{IdSend}/status` | `email:read` |\n| `/message/*`, `/senderEmail/*` (Lesen) | `email:templates:read` |\n| `/message/*`, `/senderEmail/*` (add/edit/del), `/stats/del` | `email:templates:write` |\n| `/list/list`, `/email/list` | `contacts:read` |\n| `/list/{add,edit,del}`, `/email/{add,addSingle,edit,del}`, `/import/upload` | `contacts:write` |\n| `/account/*` | `account:read` |\n\nEine Scope-Ablehnung liefert **403** mit\n`{ \"error\": \"insufficient_scope\", \"required_scope\": \"…\" }`.\n\n## Antwortformat\n\nAlle Endpunkte unterstützen `json` (Standard) und `xml`. Geben Sie das Format in der URL an:\n- `/email/list.json`\n- `/email/list.xml`\n\n## Paginierung\n\n**Gleiche Regel für die drei Mailpro-APIs** (Email v2, CRM v3, SMS): **5.000 Einträge pro Seite,\nstandardmäßig und maximal.**\n- `numberOfRecords` — Einträge pro Seite. Fehlend, `0` oder über 5.000 = 5.000.\n- `pageNumber` — Seitennummer ab 1 (Standard 1).\n- Beide werden als Query-Parameter **oder** als HTTP-Header akzeptiert.\n- Eine volle Seite bedeutet, dass es weitere geben kann: Fordern Sie die nächste Seite an, bis\n  eine unvollständige Seite zurückkommt.\n- Die Seiten sind stabil: Derselbe Aufruf liefert dieselben Einträge in derselben Reihenfolge,\n  solange sich die Daten in der Zwischenzeit nicht ändern.\n- Ausnahme: Nachrichten- und Verlaufslisten mit ihrem HTML (`bodyHTML=true`) liefern 10 Einträge pro Seite.\n- `/email/list` fügt `X-Total-Count` (die tatsächliche Gesamtzahl) und `X-Truncated: true` hinzu, wenn\n  über die Seite hinaus Kontakte verbleiben.\n\n**Unbekannte Parameter** werden ignoriert, nie abgelehnt. Enthält eine Anfrage einen Parameter, den die API\nnicht kennt, enthält die Antwort `X-Ignored-Parameters` (die Namen) und `X-Documentation` (einen Link zu\ndieser Seite), damit ein Tippfehler nicht unbemerkt bleibt.\n\n## Fehlerantworten\n\n| HTTP | Bedeutung |\n|------|---------|\n| 400  | Bad Request — fehlender oder ungültiger Pflichtparameter |\n| 401  | Unauthorized — ungültige `IdClient` oder ungültiger `ApiKey` |\n| 403  | Verboten — Kontolimit erreicht (z. B. maximale Anzahl an Listen) |\n| 404  | Nicht gefunden — die angeforderte Ressource existiert nicht |\n| 500  | Interner Serverfehler |\n\nFehler aus Geschäftsregeln:\n- `\"Not enough credit available.\"` → 403 — Ihr Konto verfügt über keine E-Mail-Credits mehr\n- `\"Email address unsubscribed.\"` → 400 — der Empfänger hat sich abgemeldet\n\n## Zustellverfolgung (transaktionale E-Mails)\n\nJede **einzeln** versendete E-Mail (`POST /send/sendmail`, die CRM API v3, das SMTP-Relay oder eine Automatisierung) erhält eine Kennung. Sie kann verfolgt werden, bis der Server des Empfängers sie annimmt oder ablehnt. Kampagnen sind hier nicht abgedeckt: Nutzen Sie die Statistiken.\n\n1. **Senden**: die Antwort von `POST /send/sendmail.{format}` enthält die Kennung der Sendung.\n2. **Ergebnis empfangen** (empfohlen): Die Webhook-Ereignisse `email.delivered` und `email.bounced` senden den endgültigen Status an Ihren Server, sobald er feststeht – ganz ohne Abfragen.\n3. **Oder abfragen**: `GET /send/{IdSend}/status.{format}` liefert den aktuellen Status (Tabelle unten).\n\n| `status` | Bedeutung | Endgültig? |\n|---|---|---|\n| `queued` | Angenommen, wartet auf den Versand. | nein |\n| `scheduled` | Für später geplant (`DatePlanned`). | nein |\n| `sent` | Von unseren Servern übergeben, noch keine Antwort des Empfängerservers. | nein |\n| `delivered` | Vom Empfängerserver angenommen (`DiagCode` = seine SMTP-Antwort). | **ja** |\n| `bounced` | Abgelehnt. `BounceType`: `hard` = ungültige Adresse oder endgültige Ablehnung; `soft` = Ablehnung nach erneuten Versuchen (Postfach voll, Server nicht erreichbar …). | **ja** |\n| `not_found` | Unbekannte Kennung oder Kennung, die nicht zu Ihrem Konto gehört. | **ja** |\n\n**Abfragen ohne Endlosschleife**\n\n- Beenden Sie die Abfragen, sobald der Status **endgültig** ist: Er ändert sich nicht mehr.\n- Erste Abfrage frühestens **5 Minuten** nach dem Versand: `delivered` erscheint etwa 5 Minuten nach der Übergabe.\n- Danach **höchstens eine Abfrage alle 15 Minuten**.\n- Fragen Sie eine nicht endgültige Sendung vor Ablauf von 15 Minuten ab, erhalten Sie dieselbe Antwort mit dem Header `Retry-After` (die Wartezeit in Sekunden), und der Aufruf zählt nicht für Ihr Kontingent.\n- **Spätestens 48 Stunden** nach dem Versand hat jede E-Mail einen endgültigen Status: Fragen Sie danach nicht mehr ab.\n- `scheduled`: Vor `DatePlanned` ist keine Abfrage nötig.\n- **Jede Abfrage zählt für Ihr Kontingent an API-Anfragen.** Nach diesen Regeln kostet eine Sendung höchstens 192 Anfragen (4 pro Stunde während 48 Stunden), in der Praxis deutlich weniger, da Sie beim endgültigen Status aufhören. Dieselbe Verfolgung per Webhook kostet ein einziges Ereignis.\n\nDie Status werden **365 Tage** aufbewahrt.\n\n## Webhooks\n\nMailpro™ kann Ihren Server in Echtzeit benachrichtigen, wenn bestimmte Ereignisse in Ihrem\nKonto eintreten (eine E-Mail wird zugestellt, eine Kampagne wird abgeschlossen, ein Kontakt erzeugt einen Bounce usw.).\nIm Stil von Stripe — Ihre URL empfängt einen HMAC-SHA256-signierten POST, sobald das\nEreignis ausgelöst wird.\n\nJedes an Ihren Webhook gesendete Ereignis zählt als 1 Anfrage in Ihrem Kontingent an API-Anfragen.\n\n### Funktionsweise\n\n1. **Abonnieren** Sie einen oder mehrere Ereignistypen über `POST /webhooks`. Die Antwort\n   enthält ein `secret`, das **einmalig** angezeigt wird (Stripe-/GitHub-Stil) — speichern Sie es.\n2. **Mailpro sendet** eine signierte JSON-Payload per POST an Ihre URL, sobald ein Ereignis übereinstimmt.\n3. **Verifizieren Sie die Signatur** serverseitig mit Ihrem `secret` (Codebeispiele unten).\n4. **Antworten Sie innerhalb von 10 Sekunden mit 200–299**. Andernfalls führen wir erneute Versuche mit\n   exponentiellem Backoff durch (10 s → 1 Min. → 5 Min. → 30 Min. → 2 Std. → 6 Std. → 24 Std., danach Abbruch).\n\n> **⏱ Aktivierungsverzögerung** — nach dem Erstellen, Aktualisieren oder Löschen eines Webhooks dauert es\n> bis zu **10 Minuten**, bis die Änderung auf allen Mailpro-API-Servern wirksam wird.\n> In diesem Zeitfenster werden Ereignisse möglicherweise noch nicht von Ihrem neuen Abonnement erfasst\n> (oder weiterhin von einem soeben entfernten erfasst). Dies ist die Zeit, die erforderlich ist, um\n> den In-Memory-Abonnement-Cache auf jeder API-Instanz zu aktualisieren.\n\n### Payload-Umschlag\n\nAlle Ereignisse teilen sich einen gemeinsamen Umschlag:\n\n```json\n{\n  \"id\":         \"evt_8f3a9b2c4d1e5f6789abcdef01234567\",\n  \"type\":       \"email.delivered\",\n  \"created\":    1748194800,\n  \"apiVersion\": \"v2\",\n  \"account\":    { \"id\": 12345, \"name\": \"ACME Corp\" },\n  \"data\":       { \"messageId\": \"...\", \"email\": \"alice@example.com\", \"...\": \"...\" }\n}\n```\n\n| Feld | Format | Beschreibung |\n|-------|--------|-------------|\n| `id` | `evt_` + 32 hex | Eindeutige Ereignis-ID — verwenden Sie sie auf Ihrer Seite als Idempotenzschlüssel. |\n| `type` | `<domain>.<verb>` | Kanonischer Ereignistyp. |\n| `created` | Unix-Sekunden UTC | In der HMAC-Signatur enthalten. |\n| `apiVersion` | `\"v2\"` | Welche Mailpro-API das Ereignis veröffentlicht hat. |\n| `account.id` | int | Ihre Mailpro-Kundennummer (= `IdClient`). |\n| `account.name` | string | Ihr Kontoname (praktisch für clientseitiges Debugging). |\n| `data` | object | Ereignis-Payload — die Struktur hängt vom `type` ab (siehe Katalog unten). |\n\n### Ereigniskatalog\n\n| Ereignis | Auslöser | `data`-Struktur |\n|-------|---------|--------------|\n| `ping` | Test über `POST /webhooks/{id}/test` | `{ message }` |\n| `email.processed` | Versand von der Pipeline akzeptiert | `{ messageId, email, campaignId, processedAt }` |\n| `email.delivered` | Eine **einzelne** E-Mail wurde vom Empfängerserver angenommen — API v2/v3, SMTP oder Automation (**nicht** Kampagnen). Aus dem PowerMTA-Zustellstrom ausgelöst. | `{ messageId, email, idSending, sendingType, diagCode, deliveredAt }` |\n| `email.opened` | Tracking-Pixel-Treffer | `{ messageId, email, campaignId, openedAt, ip, userAgent }` |\n| `email.clicked` | Klick auf einen getrackten Link | `{ messageId, email, campaignId, clickedAt, url, ip, userAgent }` |\n| `email.bounced` | Hard- oder Soft-Bounce | `{ messageId, email, campaignId, bouncedAt, bounceType, reason }` |\n| `email.spam_report` | FBL-Beschwerde | `{ messageId, email, campaignId, reportedAt }` |\n| `email.unsubscribed` | Abmelde-Link angeklickt | `{ messageId, email, campaignId, unsubscribedAt }` |\n| `email.dropped` | Vor dem Versand abgelehnt | `{ messageId, email, campaignId, droppedAt, reason }` |\n| `campaign.started` | Versand beginnt | `{ campaignId, name, totalRecipients, startedAt }` |\n| `campaign.finished` | Alle Empfänger verarbeitet | `{ campaignId, name, totalSent, totalFailed, finishedAt }` |\n| `credits.low` | E-Mail-Credit-Guthaben unter Ihrem Warnschwellenwert | `{ remaining, threshold }` |\n\nAbonnieren Sie alle Ereignisse dieser API, indem Sie `[\"*\"]` im `events`-Array übergeben.\n\n### HMAC-Signatur\n\nJeder POST enthält einen `X-Mailpro-Signature`-Header:\n\n```\nX-Mailpro-Signature: t=1748194800,v1=7f9ac2b6e4d1c8a3...\nX-Mailpro-Event-Id:  evt_8f3a9b2c4d1e5f6789abcdef01234567\nX-Mailpro-Event-Type: email.delivered\nX-Mailpro-Attempt:   1\n```\n\nSo verifizieren Sie:\n1. Extrahieren Sie `t` und `v1` aus dem Header.\n2. **Lehnen Sie ab**, falls `|now - t| > 300` (5-minütiges Replay-Schutzfenster).\n3. Berechnen Sie `expected = hex(HMAC_SHA256(secret, t + \".\" + raw_body))`.\n4. **Vergleichen Sie konstantzeit** `v1` mit `expected` (`crypto.timingSafeEqual`,\n   `hash_equals`, `CryptographicOperations.FixedTimeEquals`) — niemals `==`.\n\n#### Node.js\n\n```js\nconst crypto = require('crypto');\n\nfunction verifyMailproSignature(rawBody, header, secret) {\n  const parts = Object.fromEntries(header.split(',').map(p => p.split('=')));\n  if (Math.abs(Date.now() / 1000 - parseInt(parts.t)) > 300) return false;\n  const expected = crypto\n    .createHmac('sha256', secret)\n    .update(parts.t + '.' + rawBody)\n    .digest('hex');\n  return crypto.timingSafeEqual(\n    Buffer.from(parts.v1, 'hex'),\n    Buffer.from(expected, 'hex'));\n}\n```\n\n#### PHP\n\n```php\nfunction verifyMailproSignature(string $rawBody, string $header, string $secret): bool {\n    parse_str(str_replace(',', '&', $header), $p);\n    if (abs(time() - (int)$p['t']) > 300) return false;\n    $expected = hash_hmac('sha256', $p['t'] . '.' . $rawBody, $secret);\n    return hash_equals($expected, $p['v1']);\n}\n```\n\n#### Python\n\n```python\nimport hmac, hashlib, time\n\ndef verify_mailpro_signature(raw_body: bytes, header: str, secret: str) -> bool:\n    parts = dict(p.split('=') for p in header.split(','))\n    t = int(parts['t'])\n    if abs(time.time() - t) > 300:\n        return False\n    expected = hmac.new(\n        secret.encode(),\n        f\"{t}.\".encode() + raw_body,\n        hashlib.sha256\n    ).hexdigest()\n    return hmac.compare_digest(expected, parts['v1'])\n```\n\n#### C#\n\n```csharp\nusing System.Security.Cryptography;\nusing System.Text;\n\nstatic bool VerifyMailproSignature(string rawBody, string header, string secret) {\n    var parts = header.Split(',')\n        .Select(p => p.Split('='))\n        .ToDictionary(a => a[0], a => a[1]);\n    var t = long.Parse(parts[\"t\"]);\n    if (Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - t) > 300) return false;\n    using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret));\n    var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes($\"{t}.{rawBody}\"));\n    var expected = Convert.ToHexString(hash).ToLowerInvariant();\n    return CryptographicOperations.FixedTimeEquals(\n        Encoding.UTF8.GetBytes(expected),\n        Encoding.UTF8.GetBytes(parts[\"v1\"]));\n}\n```\n\n### Wiederholungen und automatische Deaktivierung\n\n| Versuch | Verzögerung vor dem nächsten Versuch |\n|---------|----------------------|\n| 1 → 2 | 10 Sekunden |\n| 2 → 3 | 1 Minute |\n| 3 → 4 | 5 Minuten |\n| 4 → 5 | 30 Minuten |\n| 5 → 6 | 2 Stunden |\n| 6 → 7 | 6 Stunden |\n| 7 | abgebrochen (Zustellung als `failed` markiert) |\n\nNach **10 aufeinanderfolgenden Fehlschlägen** auf demselben Webhook wird dieser **automatisch\ndeaktiviert** (`isActive: false`) und Sie erhalten eine Benachrichtigungs-E-Mail. Aktivieren Sie ihn\nmit `PUT /webhooks/{id}` erneut, sobald Ihr Endpunkt repariert ist.\n\n### Erfolg = HTTP 2xx\n\nWir betrachten Ihren Webhook nur dann als erfolgreich, wenn Sie einen Status im Bereich `200–299` zurückgeben.\nJeder 3xx/4xx/5xx oder ein Timeout (> 10 s) zählt als Fehlschlag und löst Wiederholungen aus.\nFalls Ihr Endpunkt dauerhaft nicht mehr erreichbar ist, geben Sie explizit `410 Gone` zurück — Wiederholungen\nwerden weiterhin durchgeführt, aber der Grund des Fehlschlags ist in Ihrem Zustellungsprotokoll klarer ersichtlich.\n\n### Limits\n\n| Limit | Wert |\n|-------|-------|\n| Webhooks pro Konto | 20 |\n| Abonnierte Ereignisse pro Webhook | 50 |\n| Maximale Payload-Größe | 256 KB |\n| HTTP-Timeout pro Versuch | 10 Sekunden |\n| Aufbewahrungsdauer des Zustellungsverlaufs | 30 Tage |\n"
  },
  "servers": [
    {
      "url": "https://api.mailpro.com/v2",
      "description": "Produktion"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    },
    {
      "IdClientHeader": [],
      "ApiKeyHeader": []
    },
    {
      "IdClientQuery": [],
      "ApiKeyQuery": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Bearer-JWT-Token, das über `POST /v2/token` (formularkodiert,\nPassword-Grant) bezogen wird. Dasselbe Token ist auch für die CRM API v3 und die SMS API gültig — einmal authentifizieren, jede API aufrufen.\nÜbergeben Sie es als: `Authorization: Bearer <token>`\n"
      },
      "OAuth2": {
        "type": "oauth2",
        "description": "Mailpro OAuth 2.0 — der moderne Weg für Drittanbieter-Apps und Integrationsplattformen\n(Zapier, Make, n8n), um im Namen eines Mailpro-Benutzers mit\nscoped, widerrufbaren Access-Tokens zu agieren.\n\n- **authorizationCode + PKCE** (S256, verpflichtend für öffentliche Clients) — der\n  „Mailpro verbinden\"-Einwilligungsflow. Stellt einen Access-Token + einen rotierenden\n  Refresh-Token aus.\n- **clientCredentials** — Maschine-zu-Maschine, ohne Benutzerbeteiligung.\n\nEin Autorisierungsserver für alle APIs, an der versionsneutralen Schnittstelle\n`https://api.mailpro.com/oauth/` (Issuer / `iss`-Claim\n`https://api.mailpro.com/oauth/`). Access-Tokens sind RS256-JWTs\n(verifizieren Sie diese gegen den JWKS unter `https://api.mailpro.com/oauth/.well-known/jwks`);\nTTL **20 Minuten**. Refresh-Tokens sind **30 Tage** gültig (gleitend) und\n**einmalig verwendbar** (bei jedem Refresh rotiert). Autorisierungscodes leben\n**60 Sekunden**.\n\nDerselbe OAuth-Access-Token wird von allen drei Mailpro-APIs\n(CRM v3, Email v2, SMS) akzeptiert — einmal authentifizieren, jede API aufrufen; der Zugriff wird\ndurch die Scopes des Tokens geregelt, nicht durch die API-Basis-URL. Die Legacy-Authentifizierung\n(Bearer JWT / IdClient+ApiKey) funktioniert unverändert weiter und ist NICHT\nscope-gesteuert.\n",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://api.mailpro.com/oauth/authorize",
            "tokenUrl": "https://api.mailpro.com/oauth/token",
            "refreshUrl": "https://api.mailpro.com/oauth/token",
            "scopes": {
              "contacts:read": "View your contacts, lists, tags, segments and custom fields.",
              "contacts:write": "Create, edit and delete your contacts, lists, tags and custom fields.",
              "email:send": "Send transactional and campaign emails on your behalf.",
              "email:read": "View delivery stats, opens, clicks and bounce history.",
              "email:templates:read": "View your email templates (subject, HTML, plain-text body).",
              "email:templates:write": "Create, edit and delete your email templates.",
              "sms:send": "Send transactional and campaign SMS messages on your behalf.",
              "sms:read": "View SMS credit balance and message history.",
              "sms:contacts:read": "View your SMS phone book.",
              "sms:contacts:write": "Create, edit and delete entries in your SMS phone book.",
              "webhooks:manage": "Subscribe to, edit and remove webhook endpoints for your account.",
              "account:read": "View your account credits, limits and subscription status."
            }
          },
          "clientCredentials": {
            "tokenUrl": "https://api.mailpro.com/oauth/token",
            "scopes": {
              "contacts:read": "View your contacts, lists, tags, segments and custom fields.",
              "contacts:write": "Create, edit and delete your contacts, lists, tags and custom fields.",
              "email:send": "Send transactional and campaign emails on your behalf.",
              "email:read": "View delivery stats, opens, clicks and bounce history.",
              "email:templates:read": "View your email templates (subject, HTML, plain-text body).",
              "email:templates:write": "Create, edit and delete your email templates.",
              "sms:send": "Send transactional and campaign SMS messages on your behalf.",
              "sms:read": "View SMS credit balance and message history.",
              "sms:contacts:read": "View your SMS phone book.",
              "sms:contacts:write": "Create, edit and delete entries in your SMS phone book.",
              "webhooks:manage": "Subscribe to, edit and remove webhook endpoints for your account.",
              "account:read": "View your account credits, limits and subscription status."
            }
          }
        }
      },
      "IdClientHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "IdClient",
        "description": "Ihre numerische Mailpro-Kundenkennung — **bevorzugter** Übertragungsweg (HTTP-Header).\nURLs werden von Webservern, Cloudflare und Proxies protokolliert, daher können Zugangsdaten in der Query-Zeichenkette in Zugriffslogs landen. Header werden nicht protokolliert.\n"
      },
      "ApiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "ApiKey",
        "description": "Ihr API-Schlüssel (GUID) — **bevorzugter** Übertragungsweg (HTTP-Header).\n"
      },
      "IdClientQuery": {
        "type": "apiKey",
        "in": "query",
        "name": "IdClient",
        "description": "Ihre numerische Mailpro-Kundenkennung — **veraltet**, aus Gründen der Abwärtskompatibilität beibehalten.\nWechseln Sie nach Möglichkeit zum Header `IdClient`.\n"
      },
      "ApiKeyQuery": {
        "type": "apiKey",
        "in": "query",
        "name": "ApiKey",
        "description": "Ihr API-Schlüssel (GUID) — **veraltet**, aus Gründen der Abwärtskompatibilität beibehalten.\n"
      }
    },
    "parameters": {
      "format": {
        "name": "format",
        "in": "path",
        "required": true,
        "description": "Antwortformat",
        "schema": {
          "type": "string",
          "enum": [
            "json",
            "xml"
          ],
          "default": "json"
        },
        "example": "json"
      },
      "numberOfRecords": {
        "name": "numberOfRecords",
        "in": "query",
        "description": "Einträge pro Seite — standardmäßig und maximal 5.000 (siehe Paginierung).",
        "schema": {
          "type": "integer",
          "minimum": 1
        },
        "example": 50
      },
      "pageNumber": {
        "name": "pageNumber",
        "in": "query",
        "description": "Seitennummer (1-basiert). Standardwert ist 1.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "default": 1
        },
        "example": 1
      }
    },
    "schemas": {
      "TokenResponse": {
        "type": "object",
        "properties": {
          "access_token": {
            "type": "string",
            "description": "JWT-Access-Token — verwenden Sie es als `Authorization: Bearer <token>` in nachfolgenden Anfragen."
          },
          "token_type": {
            "type": "string",
            "example": "bearer"
          },
          "expires_in": {
            "type": "integer",
            "description": "Token-Lebensdauer in Sekunden",
            "example": 31535999
          },
          "userName": {
            "type": "string",
            "description": "Kundenkennung des authentifizierten Nutzers",
            "example": "12345"
          },
          "refresh_token": {
            "type": "string",
            "description": "Token zum Bezug eines neuen Access-Tokens ohne erneute Authentifizierung"
          },
          "application": {
            "type": "string",
            "description": "Name der Integration (nur bei Drittanbieter-Grants)",
            "nullable": true
          }
        }
      },
      "List": {
        "type": "object",
        "properties": {
          "ListID": {
            "type": "integer",
            "description": "Eindeutige Kennung der Liste",
            "example": 101
          },
          "AddressBookID": {
            "type": "integer",
            "description": "**Veralteter Alias** — derselbe Wert wie `ListID`. Wird aus Gründen der Abwärtskompatibilität mit älteren Clients zurückgegeben.",
            "example": 101
          },
          "Title": {
            "type": "string",
            "description": "Anzeigename der Liste",
            "example": "Newsletter — France"
          },
          "Type": {
            "type": "integer",
            "description": "`0` = Standard-Kontaktliste, `1` = Sperrliste (zur Verwaltung von Abmeldungen)",
            "enum": [
              0,
              1
            ],
            "example": 0
          },
          "NumberEmails": {
            "type": "integer",
            "description": "Gesamtzahl der Kontakte in dieser Liste",
            "example": 4521
          },
          "CreationDate": {
            "type": "string",
            "format": "date-time",
            "description": "Datum und Uhrzeit der Listenerstellung",
            "example": "2025-01-15T10:30:00"
          }
        }
      },
      "Message": {
        "type": "object",
        "properties": {
          "IDMessage": {
            "type": "integer",
            "description": "Eindeutige Kennung der Nachrichtenvorlage",
            "example": 501
          },
          "Subject": {
            "type": "string",
            "description": "Betreffzeile der E-Mail",
            "example": "Spring Newsletter — April 2026"
          },
          "Language": {
            "type": "string",
            "description": "Sprachcode für die Lokalisierung des Abmeldelinks",
            "example": "EN"
          },
          "LinkAlign": {
            "type": "string",
            "description": "Horizontale Ausrichtung des Abmeldelinks",
            "enum": [
              "left",
              "center",
              "right"
            ],
            "example": "center"
          },
          "LinkUp": {
            "type": "integer",
            "description": "Position des Abmeldelinks — `0` = unten, `1` = oben",
            "enum": [
              0,
              1
            ],
            "example": 0
          },
          "BodyHTML": {
            "type": "string",
            "description": "Vollständiger HTML-Inhalt der E-Mail (wird nur bei `bodyHTML=true` zurückgegeben)",
            "example": "<h1>Welcome!</h1><p>This is our spring newsletter.</p>"
          },
          "UpdateDate": {
            "type": "string",
            "format": "date-time",
            "description": "Datum und Uhrzeit der letzten Änderung der Vorlage",
            "example": "2026-03-10T14:22:00"
          }
        }
      },
      "SenderEmail": {
        "type": "object",
        "properties": {
          "IDEmailExp": {
            "type": "integer",
            "description": "Eindeutige Kennung der Absender-E-Mail-Adresse",
            "example": 201
          },
          "Email": {
            "type": "string",
            "description": "Absender-E-Mail-Adresse (muss vor der Verwendung verifiziert sein)",
            "example": "newsletter@yourcompany.com"
          },
          "SenderName": {
            "type": "string",
            "description": "Anzeigename, der im E-Mail-Programm der Empfänger als Absender angezeigt wird",
            "example": "Your Company Newsletter"
          },
          "IsValid": {
            "type": "boolean",
            "description": "`true`, wenn die E-Mail-Adresse von Mailpro verifiziert wurde",
            "example": true
          },
          "CreationDate": {
            "type": "string",
            "format": "date-time",
            "example": "2025-06-01T09:00:00"
          }
        }
      },
      "Campaign": {
        "type": "object",
        "properties": {
          "IDSend": {
            "type": "integer",
            "description": "Eindeutige Kennung dieses Versands / dieser Kampagne",
            "example": 3001
          },
          "ListID": {
            "type": "integer",
            "description": "Kennung der verwendeten Empfängerliste",
            "example": 101
          },
          "AddressBookID": {
            "type": "integer",
            "description": "**Veralteter Alias** — derselbe Wert wie `ListID`.",
            "example": 101
          },
          "IDCampaign": {
            "type": "integer",
            "description": "Kennung des Kampagnen-Statistikeintrags (sofern beim Versand Campaign=1 gesetzt war)",
            "example": 8001
          },
          "SenderEmail": {
            "type": "string",
            "description": "E-Mail-Adresse des Absenders",
            "example": "newsletter@yourcompany.com"
          },
          "SenderName": {
            "type": "string",
            "description": "Anzeigename des Absenders",
            "example": "Your Company Newsletter"
          },
          "DatePlanned": {
            "type": "string",
            "format": "date-time",
            "description": "Geplantes Versanddatum und -uhrzeit",
            "example": "2026-04-20T09:00:00"
          },
          "SubjectMessage": {
            "type": "string",
            "description": "Betreffzeile der E-Mail",
            "example": "Spring Newsletter — April 2026"
          },
          "NumberCredit": {
            "type": "integer",
            "description": "Anzahl der durch diesen Versand verbrauchten E-Mail-Credits",
            "example": 4521
          }
        }
      },
      "HistoryEntry": {
        "type": "object",
        "properties": {
          "IDHistoric": {
            "type": "integer",
            "description": "Eindeutige Kennung dieses Verlaufseintrags",
            "example": 9001
          },
          "SubjectMessage": {
            "type": "string",
            "description": "Betreffzeile der versendeten E-Mail",
            "example": "Spring Newsletter — April 2026"
          },
          "DateSend": {
            "type": "string",
            "format": "date-time",
            "description": "Datum und Uhrzeit des E-Mail-Versands",
            "example": "2026-04-20T09:00:01"
          },
          "NumberSend": {
            "type": "integer",
            "description": "Gesamtzahl der in dieser Kampagne versendeten E-Mails",
            "example": 4521
          },
          "NumberOpen": {
            "type": "integer",
            "description": "Anzahl der erfassten eindeutigen Öffnungen",
            "example": 1823
          },
          "NumberClick": {
            "type": "integer",
            "description": "Anzahl der erfassten eindeutigen Linkklicks",
            "example": 342
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64",
            "description": "Webhook-Kennung (Mailpro)",
            "example": 42
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "HTTPS-Endpunkt, der Ereignisse empfängt",
            "example": "https://example.com/hooks/mailpro"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Abonnierte Ereignistypen",
            "example": [
              "email.delivered",
              "email.bounced",
              "campaign.finished"
            ]
          },
          "description": {
            "type": "string",
            "nullable": true,
            "example": "Slack integration"
          },
          "is_active": {
            "type": "boolean",
            "description": "Wenn `false`, wird kein Ereignis zugestellt. Wird nach 10 aufeinanderfolgenden Fehlversuchen automatisch deaktiviert.",
            "example": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-07-01T21:09:52.43"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "example": "2026-07-21T18:56:08.02"
          },
          "last_delivery_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true,
            "description": "Wann der letzte Zustellversuch erfolgte",
            "example": "2026-07-21T18:56:07.653"
          },
          "last_delivery_status": {
            "type": "integer",
            "nullable": true,
            "description": "HTTP-Status, den Ihr Endpunkt bei der letzten Zustellung zurückgegeben hat",
            "example": 200
          },
          "consecutive_failures": {
            "type": "integer",
            "description": "Beim ersten Erfolg auf 0 zurückgesetzt; bei 10 wird der Webhook automatisch deaktiviert",
            "example": 0
          }
        }
      },
      "WebhookList": {
        "type": "object",
        "description": "Umschlag, der von `GET /webhooks` zurückgegeben wird.",
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Webhook"
            }
          },
          "total": {
            "type": "integer",
            "description": "Gesamtzahl der Webhooks im Konto",
            "example": 2
          }
        }
      },
      "WebhookCreate": {
        "type": "object",
        "required": [
          "url",
          "events"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "HTTPS-Endpunkt (HTTP wird in der Produktion abgelehnt)",
            "example": "https://example.com/hooks/mailpro"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 50,
            "description": "Liste der zu abonnierenden Ereignistypen (siehe Katalog oben). Verwenden Sie `[\"*\"]`, um alle Ereignisse dieser API zu abonnieren.",
            "example": [
              "email.delivered",
              "email.bounced"
            ]
          },
          "description": {
            "type": "string",
            "maxLength": 500,
            "example": "Slack integration"
          }
        }
      },
      "WebhookCreateResponse": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Webhook"
          },
          {
            "type": "object",
            "properties": {
              "secret": {
                "type": "string",
                "description": "HMAC-Geheimnis. **Wird nur hier einmalig angezeigt, nie wieder.** Speichern Sie es serverseitig.",
                "example": "whsec_AbcD1234EfgH5678IjkL9012MnoP3456QrsT"
              }
            }
          }
        ]
      },
      "WebhookUpdate": {
        "type": "object",
        "description": "Teilaktualisierung — jedes Feld ist optional.",
        "properties": {
          "url": {
            "type": "string",
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 50
          },
          "description": {
            "type": "string",
            "maxLength": 500
          },
          "isActive": {
            "type": "boolean",
            "description": "Auf `true` setzen, um einen automatisch deaktivierten Webhook nach Behebung Ihres Endpunkts wieder zu aktivieren."
          }
        }
      },
      "WebhookDelivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "eventId": {
            "type": "string",
            "example": "evt_8f3a9b2c4d1e5f6789abcdef01234567"
          },
          "eventType": {
            "type": "string",
            "example": "email.delivered"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "success",
              "retrying",
              "failed"
            ]
          },
          "statusCode": {
            "type": "integer",
            "nullable": true,
            "example": 200
          },
          "responseTimeMs": {
            "type": "integer",
            "nullable": true,
            "example": 142
          },
          "attemptCount": {
            "type": "integer"
          },
          "lastError": {
            "type": "string",
            "nullable": true
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "lastAttemptAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "nextAttemptAt": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Authentication",
      "description": "Beziehen Sie ein Bearer-JWT-Token, um alle anderen API-Aufrufe zu authentifizieren. Der v2-Endpunkt `/token` ist eine 307-Weiterleitung an den kanonischen Aussteller `/v3/token` — Ihr HTTP-Client folgt der Weiterleitung transparent (POST-Methode und Body bleiben erhalten).\n"
    },
    {
      "name": "Account",
      "description": "Prüfen Sie Ihr E-Mail-Credit-Guthaben, Ihr monatliches API-Kontingent und Ihren Abonnementstatus."
    },
    {
      "name": "Lists",
      "description": "Verwalten Sie Listen (Kontaktlisten). Eine Liste gruppiert Kontakte für Massenkampagnen.\n**Maximal 1.000 Listen pro Konto** (gleiche Grenze für die drei Mailpro-APIs und in der App).\n`Type 0` = Standardliste. `Type 1` = Sperrliste (zur Verwaltung von Abmeldungen).\n"
    },
    {
      "name": "Contacts",
      "description": "Verwalten Sie einzelne E-Mail-Kontakte. Kontakte gehören zu einer oder mehreren Listen.\nVerwenden Sie den Massenimport (`/email/add`) für große Stapel oder das Hinzufügen einzelner Kontakte (`/email/addSingle`) für individuelle Anmeldungen mit benutzerdefinierten Feldwerten.\n"
    },
    {
      "name": "Messages",
      "description": "Verwalten Sie HTML-E-Mail-Vorlagen. Eine Nachrichtenvorlage speichert Ihren E-Mail-Betreff, den HTML-Body und die Konfiguration des Abmeldelinks.\nVorlagen werden über mehrere Kampagnen hinweg wiederverwendet.\n"
    },
    {
      "name": "Campaigns",
      "description": "Versenden Sie E-Mail-Massenkampagnen an eine Liste und verwalten Sie geplante Versendungen.\nEine Kampagne verwendet eine Nachrichtenvorlage und eine Absenderadresse.\n"
    },
    {
      "name": "Transactional",
      "description": "Versenden Sie einmalige transaktionale E-Mails an einzelne Empfänger.\nIm Gegensatz zu Kampagnen erfordern transaktionale E-Mails keine Liste — Sie übergeben die Empfänger-E-Mail-Adresse und den HTML-Body direkt.\n"
    },
    {
      "name": "Sender Addresses",
      "description": "Auflistung und Verwaltung validierter Absender-E-Mail-Adressen.\nNur verifizierte Adressen können als `From`-Adresse in Kampagnen verwendet werden.\n"
    },
    {
      "name": "Statistics",
      "description": "Zugriff auf Leistungskennzahlen pro Kampagne: Öffnungen, Klicks, Bounces und mehr.\nDetaillierte Aufschlüsselungen nach Stunde, Tag, Land, Betriebssystem und E-Mail-Client sind verfügbar.\n"
    },
    {
      "name": "History",
      "description": "Durchsuchen Sie das vollständige Protokoll aller bisherigen E-Mail-Versendungen.\n"
    },
    {
      "name": "Import",
      "description": "Laden Sie eine CSV- oder XLSX-Datei hoch, um E-Mail-Kontakte in einem Schritt in eine Liste zu importieren.\nDie Datei wird zur asynchronen Verarbeitung in die Warteschlange gestellt — verfolgen Sie den Abschluss über die zurückgegebene `ImportJobId` oder über den optionalen Callback `WebhookUrl`.\n"
    },
    {
      "name": "Webhooks",
      "description": "Abonnieren Sie Echtzeit-Ereignisbenachrichtigungen für Ihren Server. Mailpro sendet eine HMAC-signierte JSON-Nutzlast per POST an Ihre URL, sobald das abonnierte Ereignis eintritt.\nDen vollständigen Ereigniskatalog, den Aufbau der Nutzlast, Code-Snippets zur Signaturprüfung und die Wiederholungsstrategie finden Sie im Abschnitt „Webhooks“ in der Einführung.\n"
    },
    {
      "name": "Suppression",
      "description": "Bounces und Abmeldungen des Kontos: auflisten, hinzufügen, entfernen."
    }
  ],
  "paths": {
    "/token": {
      "post": {
        "tags": [
          "Authentication"
        ],
        "operationId": "getEmailAccessToken",
        "summary": "Access-Token beziehen (307-Weiterleitung zu /v3/token)",
        "security": [],
        "description": "Bezieht ein Bearer-JWT-Token unter Verwendung der Mailpro-Client-Zugangsdaten.\nÜbergeben Sie das zurückgegebene `access_token` in allen nachfolgenden Anfragen als `Authorization: Bearer <token>`. Dasselbe Token ist auch für die CRM API v3 und die SMS API gültig.\n\n> **⚙ Implementierungsdetail** — `POST /v2/token` ist eine **307 Temporary\n> Redirect** zu `POST /v3/token` (konfiguriert auf der IIS-`web.config`-\n> Rewrite-Ebene). HTTP 307 erhält sowohl die **Methode** (`POST`) als\n> auch den **Request-Body**, sodass jeder standardkonforme HTTP-Client\n> der Weiterleitung transparent folgt — Sie senden weiterhin POST-Anfragen\n> an `/v2/token` und erhalten ein gültiges JWT zurück. Es gibt keine\n> doppelte Token-Ausstellungslogik; die Email v2 API stellt selbst niemals\n> Tokens aus.\n\n### Unterstützte Grant-Typen\n| Grant-Typ | Anwendungsfall |\n|------------|----------|\n| `password` | Standardintegration — Benutzername + API-Schlüssel |\n| `refresh_token` | Erneuern eines ablaufenden Access-Tokens ohne erneute Authentifizierung |\n| `client_credentials` | Server-zu-Server allein mit Client-Kennung |\n\n### Token-Lebensdauer\n- Access-Token: **30 Tage**\n- Refresh-Token: **90 Tage**\n\nVerwenden Sie `grant_type=refresh_token`, um das Access-Token ohne erneute\nAuthentifizierung zu erneuern. Speichern Sie Tokens serverseitig (Vault,\nUmgebungsvariablen); betten Sie sie niemals in Browser-JS oder Mobile-App-\nBinärdateien ein. Den vollständigen Sicherheitshinweis finden Sie in der\nDokumentation des CRM-API-v3-Endpunkts `/token`.\n",
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "grant_type"
                ],
                "properties": {
                  "grant_type": {
                    "type": "string",
                    "enum": [
                      "password",
                      "refresh_token",
                      "client_credentials"
                    ],
                    "example": "password"
                  },
                  "username": {
                    "type": "string",
                    "description": "Ihr Mailpro-Benutzername (E-Mail). Erforderlich für den `password`-Grant.",
                    "example": "user@yourcompany.com"
                  },
                  "password": {
                    "type": "string",
                    "description": "Ihr Mailpro-API-Schlüssel (GUID-Format). Erforderlich für den `password`-Grant.",
                    "example": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
                  },
                  "refresh_token": {
                    "type": "string",
                    "description": "Vorheriges Refresh-Token. Erforderlich für den `refresh_token`-Grant."
                  },
                  "client_id": {
                    "type": "string",
                    "description": "Ihre Mailpro-Kundenkennung (Ganzzahl). Erforderlich für den `client_credentials`-Grant.",
                    "example": "12345"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token erfolgreich ausgestellt. Wird von `POST /v3/token` nach dem\ntransparenten 307-Follow zurückgegeben — Ihr HTTP-Client erhält ein\nnormales 200 mit derselben Body-Struktur, die er direkt vom v3-Token-\nEndpunkt erhalten würde.\n",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TokenResponse"
                },
                "example": {
                  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
                  "token_type": "bearer",
                  "expires_in": 31535999,
                  "userName": "12345",
                  "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
                  "application": null
                }
              }
            }
          },
          "307": {
            "description": "Temporäre Weiterleitung an `POST /v3/token`, ausgestellt durch die\nIIS-Rewrite-Regel in `web.config`. Standardkonforme HTTP-Clients folgen\ndieser automatisch und erhalten dabei die ursprüngliche POST-Methode\nund den Formular-Body. Nur für Clients sichtbar, die das Folgen von\nWeiterleitungen explizit deaktivieren (z. B. `curl --max-redirs 0`).\n",
            "headers": {
              "Location": {
                "schema": {
                  "type": "string"
                },
                "example": "https://api.mailpro.com/v3/token"
              }
            }
          },
          "400": {
            "description": "Ungültige Zugangsdaten oder nicht unterstützter Grant-Typ",
            "content": {
              "application/json": {
                "examples": {
                  "invalid_grant": {
                    "summary": "Falsche Zugangsdaten",
                    "value": {
                      "error": "invalid_grant",
                      "error_description": "The username or password is incorrect."
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/account/credits.{format}": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getAccountCredits",
        "security": [
          {
            "OAuth2": [
              "account:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "E-Mail-Credit-Guthaben abrufen",
        "description": "Gibt das verbleibende E-Mail-Credit-Guthaben Ihres Mailpro-Kontos zurück.\nJede versendete E-Mail verbraucht einen Credit. Credits verfallen nicht mit dem Abonnement, sind jedoch nur nutzbar, solange das Abonnement aktiv ist.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "responses": {
          "200": {
            "description": "Credit-Guthaben erfolgreich zurückgegeben",
            "content": {
              "application/json": {
                "example": {
                  "Credits": 48500
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/account/subscriptionEndDate.{format}": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getSubscriptionEndDate",
        "security": [
          {
            "OAuth2": [
              "account:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Ablaufdatum des Abonnements abrufen",
        "description": "Gibt das Ablaufdatum des aktuellen Mailpro-Abonnements zurück.\nNach dem Ablaufdatum werden Versendungen blockiert, bis das Abonnement verlängert wird.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "responses": {
          "200": {
            "description": "Ablaufdatum des Abonnements erfolgreich zurückgegeben",
            "content": {
              "application/json": {
                "example": {
                  "SubscriptionEndDate": "2027-01-15T00:00:00"
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/account/limits.{format}": {
      "get": {
        "tags": [
          "Account"
        ],
        "operationId": "getAccountLimits",
        "security": [
          {
            "OAuth2": [
              "account:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Monatliches API-Kontingent abrufen",
        "description": "Gibt das monatliche API-Anfrage-Kontingent für den authentifizierten Client zurück.\n\n**Kontingentberechnung:** Das Limit wird aus den E-Mail-Abonnement-Credits\nabgeleitet (typischerweise `subscription_credits × 5`). Bei einem Plan\nmit 10.000 E-Mails/Monat ergibt das ein monatliches Budget von 50.000\nAnfragen. Zurückgesetzt am **Jahrestag des Abonnements** (nicht am\nErsten des Kalendermonats).\n\n**Was Credits verbraucht:**\n- Jede authentifizierte API-Anfrage an die Endpunkte `v2`, `v3` oder `sms`.\n- Jedes Webhook-Ereignis, das an einen abonnierten Endpunkt zugestellt wird.\n\n**Was KOSTENLOS ist (verbraucht keine Credits):**\n- `/health`-Endpunkte.\n- Anfragen, die mit `401`, `403` oder `429` fehlschlagen.\n- Webhook-Ereignisse für Clients ohne passendes Abonnement.\n\nDas Kontingent wird **über alle 3 Mailpro-APIs** (`v2`, `v3`, `sms`)\nhinweg geteilt — ein Kunde = ein monatliches Budget für die gesamte\nPlattform.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "responses": {
          "200": {
            "description": "Momentaufnahme des Kontingents",
            "content": {
              "application/json": {
                "example": {
                  "MonthlyLimit": 50000,
                  "Remaining": 32847,
                  "Used": 17153,
                  "IsFree": false,
                  "RemainedSendsForFree": 0
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Kein Kontingent-Datensatz gefunden (neu erstelltes Konto; der Eintrag wird bei der ersten authentifizierten Anfrage angelegt)."
          }
        }
      }
    },
    "/list/list.{format}": {
      "get": {
        "tags": [
          "Lists"
        ],
        "operationId": "listLists",
        "security": [
          {
            "OAuth2": [
              "contacts:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Alle Listen auflisten",
        "description": "Gibt alle Listen des Kontos zurück, sortiert nach Erstellungsdatum (neueste zuerst), sofern nicht `sortByName=true` gesetzt ist.\nVerwenden Sie `type=0` für reguläre Listen oder `type=1` für Sperrlisten.\n\n> **Veralteter Alias:** `/addressbook/list.{format}` — derselbe Endpunkt, aus Gründen der Abwärtskompatibilität beibehalten. Neue Integrationen sollten `/list/*` verwenden.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "titleFilter",
            "in": "query",
            "description": "Nach Titel filtern (teilweise, Groß-/Kleinschreibung ignorierend)",
            "schema": {
              "type": "string"
            },
            "example": "newsletter"
          },
          {
            "name": "type",
            "in": "query",
            "description": "`0` = nur Standardlisten, `1` = nur Sperrlisten. Weglassen, um alle zurückzugeben.",
            "schema": {
              "type": "integer",
              "enum": [
                0,
                1
              ]
            }
          },
          {
            "$ref": "#/components/parameters/numberOfRecords"
          },
          {
            "$ref": "#/components/parameters/pageNumber"
          },
          {
            "name": "sortByName",
            "in": "query",
            "description": "Auf `true` setzen, um die Ergebnisse alphabetisch nach Titel zu sortieren",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Listen erfolgreich zurückgegeben.\n\n> Die Antwort enthält zusätzlich das veraltete Duplikat-Feld `AddressBookList` (identischer Inhalt), und jedes Element enthält ein veraltetes Duplikat `AddressBookID` (identisch mit `ListID`). Neue Integrationen sollten diese ignorieren.\n",
            "content": {
              "application/json": {
                "example": {
                  "Lists": [
                    {
                      "ListID": 101,
                      "Title": "Newsletter — France",
                      "Type": 0,
                      "NumberEmails": 4521,
                      "CreationDate": "2025-01-15T10:30:00"
                    },
                    {
                      "ListID": 102,
                      "Title": "Unsubscribers",
                      "Type": 1,
                      "NumberEmails": 312,
                      "CreationDate": "2025-01-15T10:31:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/list/add.{format}": {
      "post": {
        "tags": [
          "Lists"
        ],
        "operationId": "addList",
        "security": [
          {
            "OAuth2": [
              "contacts:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Liste erstellen",
        "description": "Erstellt eine neue Liste (Kontaktliste).\nDie Liste ist zunächst leer — fügen Sie Kontakte über `/email/add` oder `/email/addSingle` hinzu.\n**Maximal 1.000 Listen pro Konto** (gleiche Grenze für die drei Mailpro-APIs und in der App). Gibt HTTP 422 zurück, wenn das Limit erreicht ist.\n\n> **Veralteter Alias:** `/addressbook/add.{format}` — derselbe Endpunkt, aus Gründen der Abwärtskompatibilität beibehalten.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "Title"
                ],
                "properties": {
                  "Title": {
                    "type": "string",
                    "description": "Anzeigename für die neue Liste",
                    "example": "Spring Campaign 2026"
                  },
                  "Type": {
                    "type": "integer",
                    "description": "`0` = Standardliste (Standard), `1` = Sperrliste",
                    "enum": [
                      0,
                      1
                    ],
                    "default": 0,
                    "example": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Liste erfolgreich erstellt.\n\n> Ein veraltetes Duplikat-Feld `AddressBookList` wird ebenfalls zurückgegeben (identischer Inhalt).\n",
            "content": {
              "application/json": {
                "example": {
                  "Lists": [
                    {
                      "ListID": 103,
                      "Title": "Spring Campaign 2026",
                      "Type": 0,
                      "NumberEmails": 0,
                      "CreationDate": "2026-04-14T12:00:00"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Fehlender Titel"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "422": {
            "description": "Listenlimit (1.000) erreicht"
          }
        }
      }
    },
    "/list/edit.{format}": {
      "post": {
        "tags": [
          "Lists"
        ],
        "operationId": "editList",
        "security": [
          {
            "OAuth2": [
              "contacts:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Liste umbenennen",
        "description": "Aktualisiert den Titel einer bestehenden Liste.\nDie enthaltenen Kontakte sind davon nicht betroffen.\n\n> **Veralteter Alias:** `/addressbook/edit.{format}` — derselbe Endpunkt, aus Gründen der Abwärtskompatibilität beibehalten.\n> Der Parametername `AddressBookID` wird ebenfalls als veralteter Alias für `ListID` akzeptiert.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "ListID",
                  "Title"
                ],
                "properties": {
                  "ListID": {
                    "type": "integer",
                    "description": "Kennung der umzubenennenden Liste (aus `/list/list`). Der veraltete Alias `AddressBookID` wird ebenfalls akzeptiert.",
                    "example": 101
                  },
                  "Title": {
                    "type": "string",
                    "description": "Neuer Titel der Liste",
                    "example": "Newsletter — Europe"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Liste erfolgreich umbenannt"
          },
          "400": {
            "description": "Fehlende ListID oder fehlender Titel"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Liste nicht gefunden"
          }
        }
      }
    },
    "/list/del.{format}": {
      "post": {
        "tags": [
          "Lists"
        ],
        "operationId": "deleteList",
        "security": [
          {
            "OAuth2": [
              "contacts:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Liste löschen",
        "description": "Löscht eine Liste **und alle darin enthaltenen Kontakte** dauerhaft.\nDiese Aktion kann nicht rückgängig gemacht werden.\n\n> **Veralteter Alias:** `/addressbook/del.{format}` — derselbe Endpunkt, aus Gründen der Abwärtskompatibilität beibehalten.\n> Der Parametername `AddressBookID` wird ebenfalls als veralteter Alias für `ListID` akzeptiert.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "ListID"
                ],
                "properties": {
                  "ListID": {
                    "type": "integer",
                    "description": "Kennung der zu löschenden Liste. Der veraltete Alias `AddressBookID` wird ebenfalls akzeptiert.",
                    "example": 101
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Liste erfolgreich gelöscht",
            "content": {
              "application/json": {
                "example": {
                  "Result": "OK"
                }
              }
            }
          },
          "400": {
            "description": "Fehlende ListID"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Liste nicht gefunden"
          }
        }
      }
    },
    "/email/list.{format}": {
      "get": {
        "tags": [
          "Contacts"
        ],
        "operationId": "listEmails",
        "security": [
          {
            "OAuth2": [
              "contacts:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Kontakte auflisten",
        "description": "Gibt eine paginierte Liste der E-Mail-Kontakte des Kontos zurück.\nFiltern Sie nach Liste oder nach E-Mail-Muster.\nDie Ergebnisse sind bei `sortByName=true` alphabetisch sortiert, andernfalls nach Einfügereihenfolge.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "emailFilter",
            "in": "query",
            "description": "Nach E-Mail-Adresse filtern (teilweise, Groß-/Kleinschreibung ignorierend)",
            "schema": {
              "type": "string"
            },
            "example": "@gmail.com"
          },
          {
            "name": "listId",
            "in": "query",
            "description": "Nur Kontakte in dieser Liste zurückgeben. Der veraltete Alias `addressBookId` wird ebenfalls akzeptiert.",
            "schema": {
              "type": "integer"
            },
            "example": 101
          },
          {
            "$ref": "#/components/parameters/numberOfRecords"
          },
          {
            "$ref": "#/components/parameters/pageNumber"
          },
          {
            "name": "sortByName",
            "in": "query",
            "description": "Auf `true` setzen, um die Ergebnisse alphabetisch nach E-Mail-Adresse zu sortieren",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Kontaktliste erfolgreich zurückgegeben",
            "content": {
              "application/json": {
                "example": {
                  "Emails": [
                    {
                      "IdEmail": 10001,
                      "Email": "alice@example.com",
                      "Field1": "Alice",
                      "Field2": "Dupont"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/email/add.{format}": {
      "post": {
        "tags": [
          "Contacts"
        ],
        "operationId": "addEmails",
        "security": [
          {
            "OAuth2": [
              "contacts:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Kontakte importieren (Massenimport)",
        "description": "Importiert eine oder mehrere E-Mail-Adressen in einem einzigen Anfrageaufruf in eine Liste.\nGeben Sie die Adressen in `EmailList`, getrennt durch Semikolons, an.\n\n**Beispiel:** `alice@example.com;bob@example.com;carol@example.com`\n\nDieser Endpunkt importiert ausschließlich E-Mail-Adressen. Wenn Sie auch benutzerdefinierte Feldwerte setzen möchten, verwenden Sie stattdessen `/email/addSingle` für jeden Kontakt.\n\nZuvor abgemeldete Adressen werden stillschweigend übersprungen, sofern `Force=1` nicht gesetzt ist.\n\n**Listenauswahl:** Geben Sie `ListId` (oder den veralteten Alias `AddressBookId`) an. Mindestens einer ist erforderlich.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "EmailList"
                ],
                "properties": {
                  "ListId": {
                    "type": "integer",
                    "description": "Kennung der Zielliste. Der veraltete Alias `AddressBookId` wird ebenfalls akzeptiert.",
                    "example": 101
                  },
                  "EmailList": {
                    "type": "string",
                    "description": "Durch Semikolons getrennte zu importierende E-Mail-Adressen",
                    "example": "alice@example.com;bob@example.com;carol@example.com"
                  },
                  "Force": {
                    "type": "integer",
                    "description": "Auf `1` setzen, um zuvor abgemeldete Adressen erneut zu importieren.\nStandard: `0` (abgemeldete Adressen werden übersprungen).\n",
                    "enum": [
                      0,
                      1
                    ],
                    "default": 0,
                    "example": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kontakte erfolgreich importiert",
            "content": {
              "application/json": {
                "example": {
                  "Result": "3 contacts imported"
                }
              }
            }
          },
          "400": {
            "description": "Fehlende EmailList"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/email/addSingle.{format}": {
      "post": {
        "tags": [
          "Contacts"
        ],
        "operationId": "addSingleEmail",
        "security": [
          {
            "OAuth2": [
              "contacts:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Einzelnen Kontakt hinzufügen",
        "description": "Fügt einer Liste einen einzelnen Kontakt mit optionalen benutzerdefinierten Feldwerten hinzu.\n\n`Field1` bis `Field25` entsprechen den benutzerdefinierten Spaltendefinitionen Ihrer Liste.\nDie Zuordnung hängt von der Reihenfolge ab, in der die Spalten definiert wurden — prüfen Sie in den Listeneinstellungen in der Mailpro-Oberfläche, welche Feldnummer welcher Spalte entspricht (z. B. Field1 = Vorname, Field2 = Nachname, Field3 = Stadt …).\n\n**Listenauswahl:** Geben Sie `ListId` (oder den veralteten Alias `AddressBookId`) an.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "Email"
                ],
                "properties": {
                  "ListId": {
                    "type": "integer",
                    "description": "Kennung der Zielliste. Der veraltete Alias `AddressBookId` wird ebenfalls akzeptiert.",
                    "example": 101
                  },
                  "Email": {
                    "type": "string",
                    "description": "E-Mail-Adresse des neuen Kontakts",
                    "example": "alice@example.com"
                  },
                  "Force": {
                    "type": "integer",
                    "description": "Auf `1` setzen, um eine zuvor abgemeldete Adresse erneut hinzuzufügen",
                    "enum": [
                      0,
                      1
                    ],
                    "default": 0
                  },
                  "Field1": {
                    "type": "string",
                    "description": "Wert für benutzerdefiniertes Feld 1 (Spaltenzuordnung abhängig von Ihrer Liste)",
                    "example": "Alice"
                  },
                  "Field2": {
                    "type": "string",
                    "description": "Wert für benutzerdefiniertes Feld 2",
                    "example": "Dupont"
                  },
                  "Field3": {
                    "type": "string",
                    "description": "Wert für benutzerdefiniertes Feld 3",
                    "example": "Paris"
                  },
                  "Field4": {
                    "type": "string",
                    "description": "Wert für benutzerdefiniertes Feld 4"
                  },
                  "Field5": {
                    "type": "string",
                    "description": "Wert für benutzerdefiniertes Feld 5"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kontakt erfolgreich hinzugefügt",
            "content": {
              "application/json": {
                "example": {
                  "EmailId": 10002,
                  "Email": "alice@example.com",
                  "Field1": "Alice",
                  "Field2": "Dupont",
                  "ListID": 101
                }
              }
            }
          },
          "400": {
            "description": "Fehlende E-Mail"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/email/edit.{format}": {
      "post": {
        "tags": [
          "Contacts"
        ],
        "operationId": "editEmail",
        "security": [
          {
            "OAuth2": [
              "contacts:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Kontakt aktualisieren",
        "description": "Aktualisiert die E-Mail-Adresse und/oder die benutzerdefinierten Feldwerte eines bestehenden Kontakts.\nIdentifizieren Sie den Kontakt anhand der `EmailId` (aus `/email/list`).\nSowohl `EmailId` als auch `Email` sind erforderlich.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "EmailId",
                  "Email"
                ],
                "properties": {
                  "EmailId": {
                    "type": "integer",
                    "description": "Kennung des zu aktualisierenden Kontakts (aus `/email/list`)",
                    "example": 10001
                  },
                  "Email": {
                    "type": "string",
                    "description": "Neue E-Mail-Adresse für den Kontakt",
                    "example": "alice.updated@example.com"
                  },
                  "Field1": {
                    "type": "string",
                    "description": "Neuer Wert für benutzerdefiniertes Feld 1",
                    "example": "Alice"
                  },
                  "Field2": {
                    "type": "string",
                    "description": "Neuer Wert für benutzerdefiniertes Feld 2",
                    "example": "Dupont"
                  },
                  "Field3": {
                    "type": "string",
                    "description": "Neuer Wert für benutzerdefiniertes Feld 3"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kontakt erfolgreich aktualisiert"
          },
          "400": {
            "description": "Fehlende EmailId oder fehlende E-Mail"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Kontakt nicht gefunden"
          }
        }
      }
    },
    "/email/del.{format}": {
      "post": {
        "tags": [
          "Contacts"
        ],
        "operationId": "deleteEmail",
        "security": [
          {
            "OAuth2": [
              "contacts:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Kontakt löschen",
        "description": "Löscht einen Kontakt anhand seiner eindeutigen Kennung dauerhaft.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "EmailId"
                ],
                "properties": {
                  "EmailId": {
                    "type": "integer",
                    "description": "Kennung des zu löschenden Kontakts (aus `/email/list`)",
                    "example": 10001
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kontakt erfolgreich gelöscht"
          },
          "400": {
            "description": "Fehlende EmailId"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Kontakt nicht gefunden"
          }
        }
      }
    },
    "/message/list.{format}": {
      "get": {
        "tags": [
          "Messages"
        ],
        "operationId": "listMessages",
        "security": [
          {
            "OAuth2": [
              "email:templates:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Nachrichtenvorlagen auflisten",
        "description": "Gibt die gespeicherten HTML-E-Mail-Vorlagen des Kontos zurück.\nStandardmäßig ist der HTML-Body **nicht** in der Antwort enthalten, um die Payload klein zu halten.\nSetzen Sie `bodyHTML=true`, um ihn einzuschließen (die Ergebnisse werden dann automatisch auf 10 pro Seite begrenzt).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "subjectFilter",
            "in": "query",
            "description": "Nach Betreff filtern (teilweise, Groß-/Kleinschreibung ignorierend)",
            "schema": {
              "type": "string"
            },
            "example": "newsletter"
          },
          {
            "$ref": "#/components/parameters/numberOfRecords"
          },
          {
            "$ref": "#/components/parameters/pageNumber"
          },
          {
            "name": "bodyHTML",
            "in": "query",
            "description": "Auf `true` setzen, um den vollständigen HTML-Body in jedes Ergebnis aufzunehmen.\nBei `true` werden die Ergebnisse unabhängig von `numberOfRecords` automatisch auf 10 pro Seite begrenzt.\n",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Nachrichtenvorlagen erfolgreich zurückgegeben",
            "content": {
              "application/json": {
                "example": {
                  "MessageList": [
                    {
                      "IDMessage": 501,
                      "Subject": "Spring Newsletter — April 2026",
                      "Language": "EN",
                      "LinkAlign": "center",
                      "LinkUp": 0,
                      "UpdateDate": "2026-03-10T14:22:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/message/add.{format}": {
      "post": {
        "tags": [
          "Messages"
        ],
        "operationId": "addMessage",
        "security": [
          {
            "OAuth2": [
              "email:templates:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Nachrichtenvorlage erstellen",
        "description": "Erstellt eine neue HTML-E-Mail-Vorlage.\nDie Vorlage speichert den Betreff, den HTML-Body und die Einstellungen des Abmeldelinks.\nNach der Erstellung verwenden Sie die zurückgegebene `IDMessage` beim Starten einer Kampagne.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "Subject",
                  "BodyHTML",
                  "Language",
                  "LinkAlign",
                  "LinkUp"
                ],
                "properties": {
                  "Subject": {
                    "type": "string",
                    "description": "Betreffzeile der E-Mail (max. 255 Zeichen)",
                    "example": "Spring Newsletter — April 2026"
                  },
                  "BodyHTML": {
                    "type": "string",
                    "description": "Vollständiger HTML-Inhalt des E-Mail-Bodys",
                    "example": "<h1>Spring is here!</h1><p>Check out our latest offers.</p>"
                  },
                  "Language": {
                    "type": "string",
                    "description": "Sprachcode für die Lokalisierung des Abmeldelinks (z. B. `EN`, `FR`, `DE`)",
                    "example": "EN"
                  },
                  "LinkAlign": {
                    "type": "string",
                    "description": "Horizontale Ausrichtung des Abmeldelinks",
                    "enum": [
                      "left",
                      "center",
                      "right"
                    ],
                    "example": "center"
                  },
                  "LinkUp": {
                    "type": "integer",
                    "description": "Position des Abmeldelinks — `0` = unten in der E-Mail, `1` = oben",
                    "enum": [
                      0,
                      1
                    ],
                    "example": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nachrichtenvorlage erfolgreich erstellt",
            "content": {
              "application/json": {
                "example": {
                  "IDMessage": 502,
                  "Subject": "Spring Newsletter — April 2026",
                  "Language": "EN",
                  "LinkAlign": "center",
                  "LinkUp": 0
                }
              }
            }
          },
          "400": {
            "description": "Fehlendes Pflichtfeld"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/message/edit.{format}": {
      "post": {
        "tags": [
          "Messages"
        ],
        "operationId": "editMessage",
        "security": [
          {
            "OAuth2": [
              "email:templates:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Nachrichtenvorlage aktualisieren",
        "description": "Aktualisiert den Inhalt und die Metadaten einer bestehenden Nachrichtenvorlage.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "MessageId",
                  "Subject",
                  "BodyHTML",
                  "Language",
                  "LinkAlign",
                  "LinkUp"
                ],
                "properties": {
                  "MessageId": {
                    "type": "integer",
                    "description": "Kennung der zu aktualisierenden Nachrichtenvorlage (aus `/message/list`)",
                    "example": 501
                  },
                  "Subject": {
                    "type": "string",
                    "description": "Neue Betreffzeile der E-Mail",
                    "example": "Spring Newsletter — April 2026 (revised)"
                  },
                  "BodyHTML": {
                    "type": "string",
                    "description": "Neuer HTML-Inhalt des E-Mail-Bodys",
                    "example": "<h1>Spring is here!</h1><p>Updated content.</p>"
                  },
                  "Language": {
                    "type": "string",
                    "description": "Sprachcode für die Lokalisierung des Abmeldelinks",
                    "example": "EN"
                  },
                  "LinkAlign": {
                    "type": "string",
                    "enum": [
                      "left",
                      "center",
                      "right"
                    ],
                    "example": "center"
                  },
                  "LinkUp": {
                    "type": "integer",
                    "enum": [
                      0,
                      1
                    ],
                    "example": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nachrichtenvorlage erfolgreich aktualisiert"
          },
          "400": {
            "description": "Fehlendes Pflichtfeld"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Nachrichtenvorlage nicht gefunden"
          }
        }
      }
    },
    "/message/del.{format}": {
      "post": {
        "tags": [
          "Messages"
        ],
        "operationId": "deleteMessage",
        "security": [
          {
            "OAuth2": [
              "email:templates:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Nachrichtenvorlage löschen",
        "description": "Löscht eine Nachrichtenvorlage anhand ihrer eindeutigen Kennung dauerhaft.\nVorlagen, die von ausstehenden geplanten Kampagnen verwendet werden, können nicht gelöscht werden.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "MessageId"
                ],
                "properties": {
                  "MessageId": {
                    "type": "integer",
                    "description": "Kennung der zu löschenden Nachrichtenvorlage (aus `/message/list`)",
                    "example": 501
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Nachrichtenvorlage erfolgreich gelöscht"
          },
          "400": {
            "description": "Fehlende MessageId"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Nachrichtenvorlage nicht gefunden"
          }
        }
      }
    },
    "/send/list.{format}": {
      "get": {
        "tags": [
          "Campaigns"
        ],
        "operationId": "listCampaigns",
        "security": [
          {
            "OAuth2": [
              "email:send"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Geplante Kampagnen auflisten",
        "description": "Gibt die Liste der geplanten und kürzlich verarbeiteten E-Mail-Kampagnen zurück.\nDie Ergebnisse sind nach geplantem Versanddatum (neueste zuerst) sortiert.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "subjectMessageFilter",
            "in": "query",
            "description": "Nach Kampagnenbetreff filtern (teilweise, Groß-/Kleinschreibung ignorierend)",
            "schema": {
              "type": "string"
            },
            "example": "newsletter"
          },
          {
            "$ref": "#/components/parameters/numberOfRecords"
          },
          {
            "$ref": "#/components/parameters/pageNumber"
          }
        ],
        "responses": {
          "200": {
            "description": "Kampagnenliste erfolgreich zurückgegeben",
            "content": {
              "application/json": {
                "example": {
                  "sends": [
                    {
                      "IDSend": 3001,
                      "ListID": 101,
                      "SenderEmail": "newsletter@yourcompany.com",
                      "SenderName": "Your Company Newsletter",
                      "DatePlanned": "2026-04-20T09:00:00",
                      "SubjectMessage": "Spring Newsletter — April 2026",
                      "NumberCredit": 4521
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/send/campaign.{format}": {
      "post": {
        "tags": [
          "Campaigns"
        ],
        "operationId": "sendCampaign",
        "security": [
          {
            "OAuth2": [
              "email:send"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Kampagne starten",
        "description": "Plant oder versendet sofort eine E-Mail-Kampagne an eine Liste\nunter Verwendung einer gespeicherten Nachrichtenvorlage und einer Absenderadresse.\n\n**Erforderlich:**\n- `IDMessage` — die zu versendende Vorlage (aus `/message/list`)\n- `IDEmailExp` — die zu verwendende Absenderadresse (aus `/senderEmail/list`)\n- `ListId` — die Empfängerliste (aus `/list/list`). Der veraltete Alias `IDAddressBook` wird ebenfalls akzeptiert.\n\n**Planung:** Setzen Sie `DatePlanned` auf ein zukünftiges ISO-8601-Datum/-Uhrzeit, um den Versand zu planen.\nLassen Sie `DatePlanned` weg, um sofort zu versenden.\n\n**Statistik-Tracking:** Setzen Sie `Campaign=1` und geben Sie einen `TitleCampaign` an, um die Verfolgung von Öffnungen/Klicks/Bounces im Abschnitt Statistik zu aktivieren.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "IDMessage",
                  "IDEmailExp"
                ],
                "properties": {
                  "ListId": {
                    "type": "integer",
                    "description": "Kennung der Empfängerliste (aus `/list/list`). Der veraltete Alias `IDAddressBook` wird ebenfalls akzeptiert.",
                    "example": 101
                  },
                  "IDMessage": {
                    "type": "integer",
                    "description": "Kennung der zu versendenden Nachrichtenvorlage (aus `/message/list`)",
                    "example": 501
                  },
                  "IDEmailExp": {
                    "type": "integer",
                    "description": "Kennung der zu verwendenden Absender-E-Mail-Adresse (aus `/senderEmail/list`)",
                    "example": 201
                  },
                  "IDUnsubscribeList": {
                    "type": "integer",
                    "description": "Liste, die zum Sammeln abgemeldeter Kontakte verwendet wird (Sperrliste).\nDer veraltete Alias `IDUnsubscribeAddressBook` wird ebenfalls akzeptiert.\n",
                    "example": 102
                  },
                  "DatePlanned": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Geplantes Versanddatum/-uhrzeit (ISO 8601). Weglassen, um sofort zu versenden.",
                    "example": "2026-04-20T09:00:00"
                  },
                  "Campaign": {
                    "type": "integer",
                    "description": "Auf `1` setzen, um diesen Versand in den Statistiken als benannte Kampagne zu verfolgen",
                    "enum": [
                      0,
                      1
                    ],
                    "default": 0,
                    "example": 1
                  },
                  "TitleCampaign": {
                    "type": "string",
                    "description": "In den Statistiken angezeigter Kampagnentitel (erforderlich bei `Campaign=1`)",
                    "example": "Spring Newsletter April 2026"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kampagne erfolgreich geplant oder versendet.\n\n> Die Antwort enthält außerdem die veralteten Aliase `AddressBookID` und `UnsubscribeAddressBookID` (identisch mit `ListID` / `UnsubscribeListID`). Neue Integrationen sollten diese ignorieren.\n",
            "content": {
              "application/json": {
                "example": {
                  "send": {
                    "IDSend": 3002,
                    "ListID": 101,
                    "UnsubscribeListID": 102,
                    "IDCampaign": 8001,
                    "SenderName": "Your Company Newsletter",
                    "SenderEmail": "newsletter@yourcompany.com",
                    "DatePlanned": "2026-04-20T09:00:00",
                    "SubjectMessage": "Spring Newsletter — April 2026",
                    "NumberCredit": 4521
                  }
                }
              }
            }
          },
          "400": {
            "description": "Fehlende IDMessage oder IDEmailExp"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "403": {
            "description": "Nicht genügend E-Mail-Credits"
          },
          "404": {
            "description": "Liste, Nachricht oder Absender nicht gefunden"
          }
        }
      }
    },
    "/send/del.{format}": {
      "post": {
        "tags": [
          "Campaigns"
        ],
        "operationId": "deleteCampaign",
        "security": [
          {
            "OAuth2": [
              "email:send"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Kampagne stornieren oder löschen",
        "description": "Storniert einen **ausstehenden geplanten** Kampagnenversand oder löscht einen **abgeschlossenen** Versand.\nNur zukünftig geplante Versendungen können storniert werden — laufende Versendungen können nicht gestoppt werden.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "IdSend"
                ],
                "properties": {
                  "IdSend": {
                    "type": "integer",
                    "description": "Kennung des zu stornierenden oder zu löschenden Kampagnenversands (aus `/send/list`)",
                    "example": 3001
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kampagne erfolgreich storniert oder gelöscht",
            "content": {
              "application/json": {
                "example": {
                  "Result": "Campaign Deleted"
                }
              }
            }
          },
          "400": {
            "description": "Fehlende IdSend"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Kampagne nicht gefunden"
          }
        }
      }
    },
    "/send/scheduled.{format}": {
      "get": {
        "tags": [
          "Campaigns"
        ],
        "operationId": "listScheduledCampaigns",
        "security": [
          {
            "OAuth2": [
              "email:send"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Meine geplanten E-Mail-Kampagnen auflisten",
        "description": "Gibt die E-Mail-Kampagnen und Einzelversendungen zurück, die für ein zukünftiges Datum geplant und noch nicht versendet wurden. Nützlich vor dem Aufruf von `/cancel` oder `/reschedule`.\nDie Datensätze sind aufsteigend nach `DatePlanned` sortiert.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "$ref": "#/components/parameters/numberOfRecords"
          },
          {
            "$ref": "#/components/parameters/pageNumber"
          }
        ],
        "responses": {
          "200": {
            "description": "Liste der geplanten Kampagnen/Versendungen.\n\n> Jeder Datensatz enthält außerdem die veralteten Aliase `AddressBookID` und\n> `UnsubscribeAddressBookID` (identisch mit `ListID` / `UnsubscribeListID`).\n",
            "content": {
              "application/json": {
                "example": {
                  "sends": [
                    {
                      "IDSend": 5001,
                      "ListID": 101,
                      "UnsubscribeListID": 102,
                      "IDCampaign": 8001,
                      "SenderName": "Your Company Newsletter",
                      "SenderEmail": "newsletter@yourcompany.com",
                      "DatePlanned": "2026-05-01T09:00:00",
                      "SubjectMessage": "Spring Sale 2026",
                      "NumberCredit": 4521
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/send/{IdSend}/cancel.{format}": {
      "post": {
        "tags": [
          "Campaigns"
        ],
        "operationId": "cancelScheduledCampaign",
        "security": [
          {
            "OAuth2": [
              "email:send"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Geplante Kampagne/Versendung stornieren",
        "description": "Storniert einen geplanten E-Mail-Versand (Kampagne oder Einzelversand), der noch nicht versendet wurde.\nWurde der Versand bereits ausgeführt (oder existiert nicht / gehört einem anderen Kunden), wird **409 Conflict** zurückgegeben.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "IdSend",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 5001
          }
        ],
        "responses": {
          "200": {
            "description": "Versand storniert",
            "content": {
              "application/json": {
                "example": {
                  "Result": "OK",
                  "Cancelled": 5001
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "409": {
            "description": "Bereits versendet oder nicht gefunden"
          }
        }
      }
    },
    "/send/{IdSend}/reschedule.{format}": {
      "patch": {
        "tags": [
          "Campaigns"
        ],
        "operationId": "rescheduleCampaign",
        "security": [
          {
            "OAuth2": [
              "email:send"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Geplante Kampagne/Versendung neu planen",
        "description": "Aktualisiert das `DatePlanned` eines geplanten E-Mail-Versands. Das neue Datum muss **in der Zukunft** und **innerhalb von 90 Tagen** liegen.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "IdSend",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 5001
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "PlanDate"
                ],
                "properties": {
                  "PlanDate": {
                    "type": "string",
                    "format": "date-time",
                    "example": "2026-12-31T14:30:00"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Versand neu geplant",
            "content": {
              "application/json": {
                "example": {
                  "Result": "OK",
                  "IdSend": 5001,
                  "NewPlanDate": "2026-12-31T14:30:00"
                }
              }
            }
          },
          "400": {
            "description": "Fehlendes oder ungültiges PlanDate"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "409": {
            "description": "Bereits versendet, nicht gefunden oder neues Datum außerhalb des zulässigen Bereichs (muss in der Zukunft und innerhalb von 90 Tagen liegen)"
          }
        }
      }
    },
    "/send/mail/scheduled.{format}": {
      "get": {
        "tags": [
          "Transactional"
        ],
        "operationId": "listScheduledMails",
        "security": [
          {
            "OAuth2": [
              "email:send"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Geplante Einzel-E-Mails auflisten",
        "description": "Gibt die mit `/send/sendmail` und einem zukünftigen Datum gesendeten Einzel-E-Mails zurück, die noch nicht versendet wurden. Kampagnen werden von `/send/scheduled` aufgelistet.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "responses": {
          "200": {
            "description": "Geplante E-Mails zurückgegeben",
            "content": {
              "application/json": {
                "example": {
                  "scheduledMails": [
                    {
                      "IdSingleSend": 880123,
                      "Email": "jane@example.com",
                      "Subject": "Your invoice",
                      "DatePlanned": "2026-12-01T09:00:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/send/mail/{IdSingleSend}/cancel.{format}": {
      "post": {
        "tags": [
          "Transactional"
        ],
        "operationId": "cancelMail",
        "security": [
          {
            "OAuth2": [
              "email:send"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Geplante Einzel-E-Mail stornieren",
        "description": "Storniert die E-Mail, solange sie noch nicht versendet wurde.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "IdSingleSend",
            "in": "path",
            "required": true,
            "description": "Von `/send/sendmail` zurückgegebene `IdSingleSend`",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "E-Mail storniert",
            "content": {
              "application/json": {
                "example": {
                  "Result": "OK",
                  "Cancelled": 880123
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "409": {
            "description": "Versand nicht gefunden oder bereits erfolgt"
          }
        }
      }
    },
    "/send/mail/{IdSingleSend}/reschedule.{format}": {
      "post": {
        "tags": [
          "Transactional"
        ],
        "operationId": "rescheduleMail",
        "security": [
          {
            "OAuth2": [
              "email:send"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Geplante Einzel-E-Mail neu planen",
        "description": "Ändert das Versanddatum. Das neue Datum muss in der Zukunft und innerhalb von 90 Tagen liegen. `PATCH` wird ebenfalls akzeptiert.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "IdSingleSend",
            "in": "path",
            "required": true,
            "description": "Von `/send/sendmail` zurückgegebene `IdSingleSend`",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "PlanDate"
                ],
                "properties": {
                  "PlanDate": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Neues Versanddatum (ISO 8601)",
                    "example": "2026-12-15T09:00:00"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "E-Mail neu geplant",
            "content": {
              "application/json": {
                "example": {
                  "Result": "OK",
                  "IdSingleSend": 880123,
                  "NewPlanDate": "2026-12-15T09:00:00"
                }
              }
            }
          },
          "400": {
            "description": "Datum fehlt oder ist ungültig"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "409": {
            "description": "Versand nicht gefunden, bereits erfolgt oder Datum außerhalb des zulässigen Bereichs"
          }
        }
      }
    },
    "/send/sendingTest.{format}": {
      "post": {
        "tags": [
          "Campaigns"
        ],
        "operationId": "sendTestEmail",
        "security": [
          {
            "OAuth2": [
              "email:send"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Test-E-Mail versenden",
        "description": "Sendet eine Vorschau einer Nachrichtenvorlage an einen angegebenen Empfänger zur Überprüfung vor dem Start der eigentlichen Kampagne.\nAbsender, Vorlage und Testempfänger werden jeweils über ihre Kennungen identifiziert.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "MessageId",
                  "IDEmailExpFrom",
                  "IDEmailExpTo"
                ],
                "properties": {
                  "MessageId": {
                    "type": "integer",
                    "description": "Kennung der Nachrichtenvorlage für die Vorschau (aus `/message/list`)",
                    "example": 501
                  },
                  "IDEmailExpFrom": {
                    "type": "integer",
                    "description": "Kennung der zu verwendenden Absenderadresse (aus `/senderEmail/list`)",
                    "example": 201
                  },
                  "IDEmailExpTo": {
                    "type": "integer",
                    "description": "Kennung der Empfänger-Absenderadresse — die Test-E-Mail wird an diese Adresse gesendet",
                    "example": 202
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Test-E-Mail erfolgreich versendet",
            "content": {
              "application/json": {
                "example": {
                  "SendingTest": {
                    "IdSendingTest": 7001,
                    "ToEmail": "test@yourcompany.com",
                    "FromEmail": "newsletter@yourcompany.com",
                    "SenderName": "Your Company Newsletter"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Fehlendes Pflichtfeld"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/send/sendmail.{format}": {
      "post": {
        "tags": [
          "Transactional"
        ],
        "operationId": "sendTransactionalEmail",
        "security": [
          {
            "OAuth2": [
              "email:send"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Transaktionale E-Mail versenden",
        "description": "Versendet eine einmalige transaktionale E-Mail an einen oder mehrere Empfänger.\nIm Gegensatz zu Kampagnen erfordert dieser Endpunkt keine Liste — die Empfängeradresse und der HTML-Body werden direkt übergeben.\n\n**Erforderlich:**\n- `IDEmailExp` — die Kennung der Absenderadresse (aus `/senderEmail/list`)\n- `EmailData` — Empfänger im Format `email,field1,field2,...,field25` (durch Kommas getrennt)\n- `BodyHTML` — der HTML-Body\n- `Subject` — die Betreffzeile\n\n**EmailData-Format:** `alice@example.com,Alice,Dupont,Paris`\nDer erste Wert ist die E-Mail-Adresse; die Werte 2–26 entsprechen den Feldern Field1–Field25 für Personalisierungsvariablen in Ihrer HTML-Vorlage.\n\n**Mehrere Empfänger:** Trennen Sie mehrere `EmailData`-Einträge mit Semikolons: `alice@example.com,Alice;bob@example.com,Bob`\n\n**Planung:** Setzen Sie `DatePlanned` auf ein zukünftiges ISO-8601-Datum/-Uhrzeit, oder lassen Sie es weg, um sofort zu versenden.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "IDEmailExp",
                  "EmailData",
                  "BodyHTML",
                  "Subject"
                ],
                "properties": {
                  "IDEmailExp": {
                    "type": "integer",
                    "description": "Kennung der zu verwendenden Absender-E-Mail-Adresse (aus `/senderEmail/list`)",
                    "example": 201
                  },
                  "EmailData": {
                    "type": "string",
                    "description": "Empfänger im Format `email,feld1,feld2,...,feld25` (kommagetrennt).\nDer erste Wert ist die E-Mail-Adresse; die übrigen sind Personalisierungsfelder,\ndie Field1–Field25 in Ihrer HTML-Vorlage zugeordnet werden.\n\n**Der lokale Teil** der E-Mail (vor dem `@`) akzeptiert Buchstaben, Ziffern und\n`. _ - +` — einschließlich RFC-5322-Sub-Addressing (`user+tag@domain`, z. B. Gmail,\nFastmail, Proton). Andere von RFC 5322 erlaubte Sonderzeichen\n(z. B. `! # $ % & ' * / = ? ^ { | } ~`) sowie lokale Teile in Anführungszeichen\nwerden **nicht** akzeptiert.\n",
                    "example": "alice@example.com,Alice,Dupont,Paris"
                  },
                  "BodyHTML": {
                    "type": "string",
                    "description": "Vollständiger HTML-Inhalt des E-Mail-Bodys",
                    "example": "<p>Hello {{Field1}}, your order has been confirmed.</p>"
                  },
                  "Subject": {
                    "type": "string",
                    "description": "Betreffzeile der E-Mail (max. 255 Zeichen)",
                    "example": "Your order #12345 is confirmed"
                  },
                  "attachments": {
                    "type": "array",
                    "maxItems": 5,
                    "description": "Optionale Dateianhänge — senden Sie die Anfrage als `multipart/form-data` und fügen Sie pro Anhang einen Dateiteil hinzu (beliebiger Feldname). Bis zu **5 Dateien**, **10 MB pro Datei**, **15 MB insgesamt**. Zulässige Typen: PDF, Word, Excel, PowerPoint, Bilder (JPG, PNG, GIF, WebP), ZIP, CSV, TXT — ausführbare Dateien und Skripte werden abgelehnt. **Abrechnung:** der Versand behält sein übliches 1 Guthaben, plus **1 Guthaben pro 512 KB Anhänge über die ersten 512 KB hinaus** (Anhänge ≤ 512 KB kosten nichts extra). Alle anderen Felder dieses Endpunkts (`ReplyTo`, `ActivateStatistics`, `CustomHeaders`, …) funktionieren genau wie in der form-urlencoded-Variante.",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    }
                  },
                  "KeepInMyFiles": {
                    "type": "boolean",
                    "default": false,
                    "description": "`false` (Standard): Die Anhänge werden nur für diesen Versand verwendet — sie werden außerhalb\nIhres Kontos gespeichert, zählen nicht zu Ihrem Speicherkontingent und werden nach 35 Tagen\nautomatisch gelöscht. `true`: Die Anhänge werden zusätzlich in den Dateien Ihres Kontos gespeichert (Ordner\n`Secure/Files/Sending/api`) und zählen zu Ihrem Speicherkontingent.\n",
                    "example": false
                  }
                }
              }
            },
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "IDEmailExp",
                  "EmailData",
                  "BodyHTML",
                  "Subject"
                ],
                "properties": {
                  "IDEmailExp": {
                    "type": "integer",
                    "description": "Kennung der zu verwendenden Absender-E-Mail-Adresse (aus `/senderEmail/list`)",
                    "example": 201
                  },
                  "EmailData": {
                    "type": "string",
                    "description": "Empfänger im Format `email,feld1,feld2,...,feld25` (kommagetrennt).\nDer erste Wert ist die E-Mail-Adresse; die übrigen sind Personalisierungsfelder,\ndie Field1–Field25 in Ihrer HTML-Vorlage zugeordnet werden.\n\n**Der lokale Teil** der E-Mail (vor dem `@`) akzeptiert Buchstaben, Ziffern und\n`. _ - +` — einschließlich RFC-5322-Sub-Addressing (`user+tag@domain`, z. B. Gmail,\nFastmail, Proton). Andere von RFC 5322 erlaubte Sonderzeichen\n(z. B. `! # $ % & ' * / = ? ^ { | } ~`) sowie lokale Teile in Anführungszeichen\nwerden **nicht** akzeptiert.\n",
                    "example": "alice@example.com,Alice,Dupont,Paris"
                  },
                  "BodyHTML": {
                    "type": "string",
                    "description": "Vollständiger HTML-Inhalt des E-Mail-Bodys",
                    "example": "<p>Hello {{Field1}}, your order has been confirmed.</p>"
                  },
                  "Subject": {
                    "type": "string",
                    "description": "Betreffzeile der E-Mail (max. 255 Zeichen)",
                    "example": "Your order #12345 is confirmed"
                  },
                  "attachments": {
                    "type": "string",
                    "description": "Optionale Dateianhänge als **JSON-Array** von `{ \"filename\": …, \"content\": … }`-Objekten, wobei `content` **Base64-codiert** ist (gleiches Format wie die CRM API v3). Bis zu **5 Dateien**, **10 MB pro Datei** und **15 MB insgesamt** (nach der Decodierung). Gängige Dokument- und Bildformate werden akzeptiert; ausführbare Dateien und Skripte werden abgelehnt. **Abrechnung:** Der Versand behält sein übliches 1 Credit, plus **1 Credit pro 512 KB Anhänge über die ersten 512 KB hinaus**. *Alternativ können Sie die Dateien als `multipart/form-data`-Teile senden (siehe den Multipart-Request-Body oben) — beides funktioniert.*",
                    "example": "[{\"filename\":\"invoice.pdf\",\"content\":\"JVBERi0xLjQK...\"}]"
                  },
                  "KeepInMyFiles": {
                    "type": "boolean",
                    "default": false,
                    "description": "`false` (Standard): Die Anhänge werden nur für diesen Versand verwendet — sie werden außerhalb\nIhres Kontos gespeichert, zählen nicht zu Ihrem Speicherkontingent und werden nach 35 Tagen\nautomatisch gelöscht. `true`: Die Anhänge werden zusätzlich in den Dateien Ihres Kontos gespeichert (Ordner\n`Secure/Files/Sending/api`) und zählen zu Ihrem Speicherkontingent.\n",
                    "example": false
                  },
                  "DatePlanned": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Geplantes Versanddatum/-uhrzeit (ISO 8601). Weglassen, um sofort zu versenden.",
                    "example": "2026-04-15T14:30:00"
                  },
                  "ActivateStatistics": {
                    "type": "boolean",
                    "description": "Auf `true` setzen, um Öffnungen und Klicks für diese E-Mail zu verfolgen",
                    "default": false,
                    "example": true
                  },
                  "ReplyTo": {
                    "type": "string",
                    "description": "Antwortadresse (Reply-to). Wenn ausgelassen, gehen Antworten an die Absenderadresse.",
                    "example": "support@yourcompany.com"
                  },
                  "UnsubscriptionLink": {
                    "type": "boolean",
                    "description": "Auf `true` setzen, um einen Abmeldelink an den E-Mail-Body anzuhängen",
                    "default": false,
                    "example": false
                  },
                  "CustomHeaders": {
                    "type": "string",
                    "description": "Zusätzliche SMTP-Header als durch Semikolons getrennte `key=value`-Zeichenkette",
                    "example": "X-Campaign-ID=campaign_42;X-Priority=1"
                  },
                  "BodyText": {
                    "type": "string",
                    "description": "Reintext-Fallback für E-Mail-Clients, die kein HTML darstellen",
                    "example": "Hello Alice, your order has been confirmed."
                  },
                  "List_Unsubscribe": {
                    "type": "string",
                    "description": "Wert für den E-Mail-Header `List-Unsubscribe` (URL oder mailto)",
                    "example": "https://yourcompany.com/unsubscribe?token=abc123"
                  },
                  "List_Unsubscribe_Post": {
                    "type": "string",
                    "description": "Wert für den Header `List-Unsubscribe-Post` (RFC 8058)",
                    "example": "List-Unsubscribe=One-Click"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Transaktionale E-Mail erfolgreich versendet oder geplant",
            "content": {
              "application/json": {
                "example": {
                  "SingleSend": {
                    "IdSingleSend": 8001,
                    "IdEmailExp": 201,
                    "DatePlanned": "2026-04-15T14:30:00",
                    "Subject": "Your order #12345 is confirmed",
                    "Email": "alice@example.com",
                    "Field1": "Alice",
                    "Field2": "Dupont",
                    "UnsubscriptionLink": false,
                    "ActivateStatistics": true
                  }
                }
              }
            }
          },
          "400": {
            "description": "Fehlendes Pflichtfeld oder ungültiges E-Mail-Format"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "403": {
            "description": "Nicht genügend E-Mail-Credits"
          },
          "404": {
            "description": "Absender nicht gefunden oder E-Mail-Adresse abgemeldet"
          }
        }
      }
    },
    "/send/{IdSend}/status.{format}": {
      "get": {
        "tags": [
          "Transactional"
        ],
        "operationId": "getTransactionalStatus",
        "security": [
          {
            "OAuth2": [
              "email:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Zustellstatus einer transaktionalen E-Mail abrufen",
        "description": "Gibt den aktuellen Zustellstatus einer transaktionalen E-Mail zurück, die über `/send/sendmail` gesendet wurde. Übergeben Sie die `IdSingleSend`, die dieser Aufruf zurückgegeben hat.\n\nMögliche Werte: `delivered` (vom Empfängerserver angenommen, siehe `DiagCode`), `bounced` (abgelehnt — `BounceType: hard` ungültige Adresse oder endgültige Ablehnung, `soft` Ablehnung nach erneuten Versuchen), `sent` (an den Mailserver übergeben, noch keine Antwort), `scheduled` (noch nicht gesendet, `DatePlanned` in der Zukunft) und `queued` (wartet auf den Versand). `delivered` und `bounced` sind endgültig: Beenden Sie die Abfragen. Jede E-Mail hat spätestens 48 Stunden nach dem Versand einen endgültigen Status; fragen Sie höchstens alle 15 Minuten ab (jeder Aufruf zählt für Ihr API-Kontingent) oder nutzen Sie die Webhooks `email.delivered` / `email.bounced`. Nur der Kunde, der die E-Mail gesendet hat, kann ihren Status lesen — jede andere ID liefert 404.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "IdSend",
            "in": "path",
            "required": true,
            "description": "Die von `/send/sendmail` zurückgegebene `IdSingleSend`.",
            "schema": {
              "type": "integer"
            },
            "example": 8001
          }
        ],
        "responses": {
          "200": {
            "description": "Aktueller Zustellstatus",
            "content": {
              "application/json": {
                "example": {
                  "status": {
                    "IdSingleSend": 8001,
                    "Email": "alice@example.com",
                    "Status": "delivered",
                    "DatePlanned": "2026-04-15T14:30:00",
                    "StatusDate": "2026-04-15T14:30:07",
                    "DiagCode": "2.0.0 (success)",
                    "BounceType": null
                  }
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Kein transaktionaler Versand mit dieser ID für diesen Kunden gefunden"
          }
        }
      }
    },
    "/senderEmail/list.{format}": {
      "get": {
        "tags": [
          "Sender Addresses"
        ],
        "operationId": "listSenderEmails",
        "security": [
          {
            "OAuth2": [
              "email:templates:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Validierte Absenderadressen auflisten",
        "description": "Gibt die Liste der für das Konto konfigurierten Absender-E-Mail-Adressen zurück.\nNur Adressen mit `IsValid: true` können beim Versenden von Kampagnen verwendet werden.\nNeue Adressen werden mit `/senderEmail/add` hinzugefügt und sind gültig, sobald der Link in der Bestätigungs-E-Mail angeklickt wurde.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "emailFilter",
            "in": "query",
            "description": "Nach E-Mail-Adresse filtern (teilweise, Groß-/Kleinschreibung ignorierend)",
            "schema": {
              "type": "string"
            },
            "example": "@yourcompany.com"
          },
          {
            "$ref": "#/components/parameters/numberOfRecords"
          },
          {
            "$ref": "#/components/parameters/pageNumber"
          },
          {
            "name": "sortByName",
            "in": "query",
            "description": "Auf `true` setzen, um die Ergebnisse alphabetisch nach Absendername zu sortieren",
            "schema": {
              "type": "boolean",
              "default": false
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Absenderadressen erfolgreich zurückgegeben",
            "content": {
              "application/json": {
                "example": {
                  "ExpEmailList": [
                    {
                      "IDEmailExp": 201,
                      "Email": "newsletter@yourcompany.com",
                      "SenderName": "Your Company Newsletter",
                      "IsValid": true,
                      "CreationDate": "2025-06-01T09:00:00"
                    },
                    {
                      "IDEmailExp": 202,
                      "Email": "support@yourcompany.com",
                      "SenderName": "Your Company Support",
                      "IsValid": true,
                      "CreationDate": "2025-06-01T09:05:00"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/senderEmail/add.{format}": {
      "post": {
        "tags": [
          "Sender Addresses"
        ],
        "operationId": "addSenderEmail",
        "security": [
          {
            "OAuth2": [
              "email:templates:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Absenderadresse hinzufügen",
        "description": "Fügt die Adresse mit denselben Prüfungen wie in der Anwendung hinzu und sendet ihr eine Bestätigungs-E-Mail. Sie kann verwendet werden, sobald der Link in dieser E-Mail angeklickt wurde. Ein Konto kann bis zu 25 Absender haben, bestätigt oder ausstehend.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "Email",
                  "SenderName"
                ],
                "properties": {
                  "Email": {
                    "type": "string",
                    "description": "Absenderadresse",
                    "example": "news@example.com"
                  },
                  "SenderName": {
                    "type": "string",
                    "description": "Den Empfängern angezeigter Name",
                    "example": "Example News"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Adresse hinzugefügt. `DomainHasMx` ist false, wenn die Domain keinen MX-Eintrag hat.",
            "content": {
              "application/json": {
                "example": {
                  "Result": "OK",
                  "ConfirmationSent": true,
                  "DomainHasMx": true
                }
              }
            }
          },
          "400": {
            "description": "`Email` oder `SenderName` fehlt"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "422": {
            "description": "Adresse abgelehnt: ungültig, bereits unter den Absendern des Kontos, öffentliche E-Mail-Domain, unzulässiger Name oder Limit von 25 erreicht. Die Meldung nennt den Grund."
          },
          "503": {
            "description": "Vorübergehend nicht verfügbar, bitte versuchen Sie es erneut"
          }
        }
      }
    },
    "/senderEmail/{IdSenderEmail}/resendValidation.{format}": {
      "post": {
        "tags": [
          "Sender Addresses"
        ],
        "operationId": "resendSenderValidation",
        "security": [
          {
            "OAuth2": [
              "email:templates:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Bestätigungs-E-Mail erneut senden",
        "description": "Für eine Adresse, die noch auf die Bestätigung wartet.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "IdSenderEmail",
            "in": "path",
            "required": true,
            "description": "ID des Absenders aus `/senderEmail/list`",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "E-Mail erneut gesendet",
            "content": {
              "application/json": {
                "example": {
                  "Result": "OK",
                  "ConfirmationSent": true
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Absender nicht gefunden"
          },
          "409": {
            "description": "Dieser Absender ist bereits bestätigt"
          },
          "503": {
            "description": "Vorübergehend nicht verfügbar, bitte versuchen Sie es erneut"
          }
        }
      }
    },
    "/senderEmail/{IdSenderEmail}/authentication.{format}": {
      "get": {
        "tags": [
          "Sender Addresses"
        ],
        "operationId": "getSenderAuthentication",
        "security": [
          {
            "OAuth2": [
              "email:templates:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Domain eines Absenders prüfen (SPF, DKIM, DMARC, MX)",
        "description": "Prüft die Domain live im DNS und gibt die zu veröffentlichenden Einträge zurück. Nur Lesezugriff. DKIM wird in der Anwendung aktiviert: `DkimSettingsUrl` öffnet die richtige Seite.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "IdSenderEmail",
            "in": "path",
            "required": true,
            "description": "ID des Absenders aus `/senderEmail/list`",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Status der Domain. `Spf.RecommendedRecord` basiert auf Ihrem aktuellen Eintrag: Veröffentlichen Sie ihn nur, wenn `Spf.ChangeNeeded` true ist.",
            "content": {
              "application/json": {
                "example": {
                  "Domain": "example.com",
                  "Spf": {
                    "Valid": true,
                    "Record": "v=spf1 include:spf.mailpro.com -all",
                    "RecommendedRecord": "v=spf1 include:spf.mailpro.com -all",
                    "ChangeNeeded": false
                  },
                  "Dkim": {
                    "Valid": true,
                    "Records": [
                      {
                        "Host": "key._domainkey.example.com",
                        "Value": "v=DKIM1;k=rsa;p=MIIBIjANBgkq...",
                        "Validated": true
                      }
                    ]
                  },
                  "Dmarc": {
                    "Valid": true,
                    "Record": "v=DMARC1; p=quarantine"
                  },
                  "Mx": {
                    "Valid": true,
                    "Record": "mail.example.com"
                  },
                  "DkimSettingsUrl": "https://app.mailpro.com/dkim/list?d=example.com"
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Absender nicht gefunden"
          },
          "503": {
            "description": "Vorübergehend nicht verfügbar, bitte versuchen Sie es erneut"
          }
        }
      }
    },
    "/senderEmail/del.{format}": {
      "post": {
        "tags": [
          "Sender Addresses"
        ],
        "operationId": "deleteSenderEmail",
        "security": [
          {
            "OAuth2": [
              "email:templates:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Absenderadresse entfernen",
        "description": "Entfernt eine validierte Absender-E-Mail-Adresse aus dem Konto.\nAbsenderadressen, die von geplanten Kampagnen verwendet werden, können nicht gelöscht werden.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "idEmailExp"
                ],
                "properties": {
                  "idEmailExp": {
                    "type": "integer",
                    "description": "Kennung der zu entfernenden Absenderadresse (aus `/senderEmail/list`)",
                    "example": 201
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Absenderadresse erfolgreich entfernt",
            "content": {
              "application/json": {
                "example": {
                  "Result": "EmailSender Deleted"
                }
              }
            }
          },
          "400": {
            "description": "Fehlende idEmailExp"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/stats/list.{format}": {
      "get": {
        "tags": [
          "Statistics"
        ],
        "operationId": "listStats",
        "security": [
          {
            "OAuth2": [
              "email:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Kampagnenstatistiken auflisten",
        "description": "Gibt Gesamtleistungskennzahlen für alle Kampagnen zurück: Anzahl der Versendungen, Öffnungsrate, Klickrate, Anzahl der Bounces. Filtern Sie nach Datumsbereich oder Kampagnentitel.\nDie Ergebnisse sind nach Versanddatum (neueste zuerst) sortiert.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "titleCampaignFilter",
            "in": "query",
            "description": "Nach Kampagnentitel filtern (teilweise, Groß-/Kleinschreibung ignorierend)",
            "schema": {
              "type": "string"
            },
            "example": "spring"
          },
          {
            "$ref": "#/components/parameters/numberOfRecords"
          },
          {
            "$ref": "#/components/parameters/pageNumber"
          },
          {
            "name": "dateStart",
            "in": "query",
            "description": "Beginn des Datumsbereichsfilters (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-01-01T00:00:00"
          },
          {
            "name": "dateEnd",
            "in": "query",
            "description": "Ende des Datumsbereichsfilters (ISO 8601)",
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "example": "2026-12-31T23:59:59"
          }
        ],
        "responses": {
          "200": {
            "description": "Kampagnenstatistiken erfolgreich zurückgegeben",
            "content": {
              "application/json": {
                "example": {
                  "Campaigns": [
                    {
                      "IdCampaign": 8001,
                      "DateCampaign": "2026-04-20T09:00:01",
                      "TitleCampaign": "Spring Newsletter April 2026",
                      "NumberEmailSend": 4521,
                      "NumberEmailOpen": 1823,
                      "NumberEmailClick": 342,
                      "BadMail": 12,
                      "NumberUnsubscribers": 8,
                      "NumberComplaints": 1,
                      "SpamTrap": 0,
                      "DeliverabilityScore": 98
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/stats/byHour.{format}": {
      "get": {
        "tags": [
          "Statistics"
        ],
        "operationId": "getStatsByHour",
        "security": [
          {
            "OAuth2": [
              "email:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Statistik nach Stunde",
        "description": "Gibt die stündliche Aufschlüsselung der Öffnungen und Klicks für eine bestimmte Kampagne zurück.\nNützlich, um die optimale Versandzeit zu ermitteln.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "idCampaign",
            "in": "query",
            "required": true,
            "description": "Kennung der Kampagne (aus `/stats/list`)",
            "schema": {
              "type": "integer"
            },
            "example": 8001
          }
        ],
        "responses": {
          "200": {
            "description": "Stündliche Statistiken erfolgreich zurückgegeben",
            "content": {
              "application/json": {
                "example": {
                  "ByHour": [
                    {
                      "Hour": 9,
                      "Opens": 823,
                      "Clicks": 142
                    },
                    {
                      "Hour": 10,
                      "Opens": 512,
                      "Clicks": 98
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/stats/byDay.{format}": {
      "get": {
        "tags": [
          "Statistics"
        ],
        "operationId": "getStatsByDay",
        "security": [
          {
            "OAuth2": [
              "email:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Statistik nach Tag",
        "description": "Gibt die tägliche Aufschlüsselung der Öffnungen und Klicks für eine bestimmte Kampagne zurück.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "idCampaign",
            "in": "query",
            "required": true,
            "description": "Kennung der Kampagne (aus `/stats/list`)",
            "schema": {
              "type": "integer"
            },
            "example": 8001
          }
        ],
        "responses": {
          "200": {
            "description": "Tägliche Statistiken erfolgreich zurückgegeben"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/stats/del.{format}": {
      "post": {
        "tags": [
          "Statistics"
        ],
        "operationId": "deleteStats",
        "security": [
          {
            "OAuth2": [
              "email:templates:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Kampagnenstatistiken löschen",
        "description": "Löscht alle Statistikdatensätze für eine bestimmte Kampagne dauerhaft.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "IdCampaign"
                ],
                "properties": {
                  "IdCampaign": {
                    "type": "integer",
                    "description": "Kennung der Kampagne, deren Statistiken gelöscht werden sollen (aus `/stats/list`)",
                    "example": 8001
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kampagnenstatistiken erfolgreich gelöscht",
            "content": {
              "application/json": {
                "example": {
                  "Result": "Statistic Deleted"
                }
              }
            }
          },
          "400": {
            "description": "Fehlende IdCampaign"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Kampagne nicht gefunden"
          }
        }
      }
    },
    "/stats/country.{format}": {
      "get": {
        "tags": [
          "Statistics"
        ],
        "operationId": "statsCountry",
        "security": [
          {
            "OAuth2": [
              "email:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Geolokalisierungs-Aufschlüsselung",
        "description": "Gibt die geografische Aufschlüsselung der Kampagnenöffnungen zurück — wie viele Öffnungen aus welchem Land kamen.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "idCampaign",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 8001
          }
        ],
        "responses": {
          "200": {
            "description": "Aufschlüsselung nach Land zurückgegeben"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/stats/open.{format}": {
      "get": {
        "tags": [
          "Statistics"
        ],
        "operationId": "statsOpens",
        "security": [
          {
            "OAuth2": [
              "email:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Protokoll der Öffnungsereignisse",
        "description": "Gibt das Protokoll der Öffnungsereignisse pro Empfänger für eine Kampagne zurück (eine Zeile pro Öffnung).\nVerwenden Sie `emailFilter`, um nach einem bestimmten Empfänger zu suchen (teilweise, Groß-/Kleinschreibung ignorierend).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "idCampaign",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 8001
          },
          {
            "name": "emailFilter",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "example": "@gmail.com"
          },
          {
            "$ref": "#/components/parameters/numberOfRecords"
          },
          {
            "$ref": "#/components/parameters/pageNumber"
          }
        ],
        "responses": {
          "200": {
            "description": "Öffnungsereignisse zurückgegeben"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/stats/click.{format}": {
      "get": {
        "tags": [
          "Statistics"
        ],
        "operationId": "statsClicks",
        "security": [
          {
            "OAuth2": [
              "email:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Protokoll der Klickereignisse",
        "description": "Gibt das Protokoll der Klickereignisse pro Empfänger für eine Kampagne zurück — einschließlich des angeklickten Links und des Zeitpunkts.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "idCampaign",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 8001
          },
          {
            "name": "emailFilter",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/numberOfRecords"
          },
          {
            "$ref": "#/components/parameters/pageNumber"
          }
        ],
        "responses": {
          "200": {
            "description": "Klickereignisse zurückgegeben"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/stats/system.{format}": {
      "get": {
        "tags": [
          "Statistics"
        ],
        "operationId": "statsSystem",
        "security": [
          {
            "OAuth2": [
              "email:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Aufschlüsselung nach Betriebssystem",
        "description": "Gibt die Aufschlüsselung der Öffnungen nach Betriebssystem (Windows, macOS, iOS, Android, Linux usw.) für eine bestimmte Kampagne zurück.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "idCampaign",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 8001
          }
        ],
        "responses": {
          "200": {
            "description": "Aufschlüsselung nach Betriebssystem zurückgegeben"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/stats/emailSoftware.{format}": {
      "get": {
        "tags": [
          "Statistics"
        ],
        "operationId": "statsEmailSoftware",
        "security": [
          {
            "OAuth2": [
              "email:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Aufschlüsselung nach E-Mail-Client",
        "description": "Gibt die Aufschlüsselung der Öffnungen nach E-Mail-Client (Gmail, Outlook, Apple Mail, Thunderbird usw.) für eine bestimmte Kampagne zurück.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "idCampaign",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 8001
          }
        ],
        "responses": {
          "200": {
            "description": "Aufschlüsselung nach E-Mail-Client zurückgegeben"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/stats/bounce.{format}": {
      "get": {
        "tags": [
          "Statistics"
        ],
        "operationId": "statsBounce",
        "security": [
          {
            "OAuth2": [
              "email:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Bounce-Protokoll",
        "description": "Gibt die Liste der zurückgewiesenen Empfänger (Hard Bounces, Soft Bounces,\nSpam-Beschwerden) einer Kampagne zurück, mit dem Fehlergrund für jede Adresse.\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "idCampaign",
            "in": "query",
            "required": true,
            "schema": {
              "type": "integer"
            },
            "example": 8001
          },
          {
            "name": "emailFilter",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "$ref": "#/components/parameters/numberOfRecords"
          },
          {
            "$ref": "#/components/parameters/pageNumber"
          }
        ],
        "responses": {
          "200": {
            "description": "Zurückgegebene Bounce-Ereignisse",
            "content": {
              "application/json": {
                "example": {
                  "ListBadMail": [
                    {
                      "Email": "bounce@example.com",
                      "Date": "2026-04-20T09:05:12",
                      "Error": "550 5.1.1 recipient rejected",
                      "AddressbookId": 1813318
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/suppression/bounces.{format}": {
      "get": {
        "tags": [
          "Suppression"
        ],
        "operationId": "listBounces",
        "security": [
          {
            "OAuth2": [
              "email:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Bounces des Kontos auflisten",
        "description": "Die neuesten zuerst. Die Gesamtzahl steht im Header `X-Total-Count`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "type",
            "in": "query",
            "description": "`hard` oder `soft`",
            "schema": {
              "type": "string",
              "enum": [
                "hard",
                "soft"
              ]
            }
          },
          {
            "name": "source",
            "in": "query",
            "description": "Herkunft des Bounces: `list`, `contact`, `api` oder `smtp`",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "email",
            "in": "query",
            "description": "Genaue Adresse",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dateFrom",
            "in": "query",
            "description": "Ab diesem Datum",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "dateTo",
            "in": "query",
            "description": "Bis zu diesem Datum",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "numberOfRecords",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "pageNumber",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Bounces zurückgegeben",
            "content": {
              "application/json": {
                "example": {
                  "bounces": [
                    {
                      "Id": 5521,
                      "Source": "contact",
                      "BounceType": "hard",
                      "Email": "old@example.com",
                      "Date": "2026-10-12T08:30:00",
                      "DiagCode": "550 5.1.1 User unknown",
                      "IdList": 101
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "`type` muss `hard` oder `soft` sein"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/suppression/bounces/{Id}/del.{format}": {
      "post": {
        "tags": [
          "Suppression"
        ],
        "operationId": "deleteBounce",
        "security": [
          {
            "OAuth2": [
              "contacts:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Bounce entfernen",
        "description": "`Source` und `Type` sind erforderlich, wie von `/suppression/bounces` zurückgegeben: Eine `Id` allein ist nicht eindeutig.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "Id",
            "in": "path",
            "required": true,
            "description": "`Id` des Bounces",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "Source",
                  "Type"
                ],
                "properties": {
                  "Source": {
                    "type": "string",
                    "description": "`list`, `contact`, `api` oder `smtp`"
                  },
                  "Type": {
                    "type": "string",
                    "enum": [
                      "hard",
                      "soft"
                    ],
                    "description": "`hard` oder `soft`"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Bounce entfernt",
            "content": {
              "application/json": {
                "example": {
                  "Result": "OK",
                  "Id": 5521,
                  "Restored": false
                }
              }
            }
          },
          "400": {
            "description": "`Source` oder `Type` fehlt"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Bounce nicht gefunden"
          }
        }
      }
    },
    "/suppression/bounces/{Id}/restore.{format}": {
      "post": {
        "tags": [
          "Suppression"
        ],
        "operationId": "restoreBounce",
        "security": [
          {
            "OAuth2": [
              "contacts:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Kontakt mit Hard Bounce wieder in seine Listen aufnehmen",
        "description": "Nur für einen Hard Bounce mit der Herkunft `contact`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "Id",
            "in": "path",
            "required": true,
            "description": "`Id` des Bounces",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Kontakt wieder aufgenommen",
            "content": {
              "application/json": {
                "example": {
                  "Result": "OK",
                  "Id": 5521,
                  "Restored": true
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Hard Bounce eines Kontakts nicht gefunden oder Adresse nicht mehr aktiv"
          }
        }
      }
    },
    "/suppression/unsubscribers.{format}": {
      "get": {
        "tags": [
          "Suppression"
        ],
        "operationId": "listUnsubscribers",
        "security": [
          {
            "OAuth2": [
              "contacts:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Abmeldungen des Kontos auflisten",
        "description": "Die neuesten zuerst. Die Gesamtzahl steht im Header `X-Total-Count`.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "source",
            "in": "query",
            "description": "Herkunft der Abmeldung: `contact`, `list`, `smtp`, `api` oder `api3`",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "email",
            "in": "query",
            "description": "Genaue Adresse",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dateFrom",
            "in": "query",
            "description": "Ab diesem Datum",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "dateTo",
            "in": "query",
            "description": "Bis zu diesem Datum",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "numberOfRecords",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "pageNumber",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Abmeldungen zurückgegeben",
            "content": {
              "application/json": {
                "example": {
                  "unsubscribers": [
                    {
                      "Id": 9012,
                      "Source": "api",
                      "Email": "stop@example.com",
                      "Date": "2026-10-20T16:05:00",
                      "ListName": null,
                      "Comment": "Asked by phone"
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/suppression/unsubscribers/add.{format}": {
      "post": {
        "tags": [
          "Suppression"
        ],
        "operationId": "addUnsubscriber",
        "security": [
          {
            "OAuth2": [
              "contacts:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Abmeldung hinzufügen",
        "description": "Ohne `ListId` wird die Adresse für das gesamte Konto abgemeldet. Mit `ListId` nur von dieser Abmeldeliste.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "Email"
                ],
                "properties": {
                  "Email": {
                    "type": "string",
                    "description": "Abzumeldende Adresse",
                    "example": "stop@example.com"
                  },
                  "Comment": {
                    "type": "string",
                    "description": "Freier Kommentar",
                    "example": "Asked by phone"
                  },
                  "ListId": {
                    "type": "integer",
                    "format": "int64",
                    "description": "Abmeldeliste des Kontos (optional)"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Erledigt. `AlreadyUnsubscribed` ist true, wenn die Adresse bereits abgemeldet war.",
            "content": {
              "application/json": {
                "example": {
                  "Result": "OK",
                  "AlreadyUnsubscribed": false
                }
              }
            }
          },
          "400": {
            "description": "Eine gültige Adresse ist erforderlich"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "`ListId` ist keine Abmeldeliste dieses Kontos"
          }
        }
      }
    },
    "/suppression/unsubscribers/{Id}/del.{format}": {
      "post": {
        "tags": [
          "Suppression"
        ],
        "operationId": "deleteUnsubscriber",
        "security": [
          {
            "OAuth2": [
              "contacts:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Abmeldung entfernen",
        "description": "`Source` ist erforderlich, wie von `/suppression/unsubscribers` zurückgegeben: Eine `Id` allein ist nicht eindeutig.",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "Id",
            "in": "path",
            "required": true,
            "description": "`Id` der Abmeldung",
            "schema": {
              "type": "integer",
              "format": "int64"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/x-www-form-urlencoded": {
              "schema": {
                "type": "object",
                "required": [
                  "Source"
                ],
                "properties": {
                  "Source": {
                    "type": "string",
                    "description": "`contact`, `list`, `smtp`, `api` oder `api3`"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Abmeldung entfernt",
            "content": {
              "application/json": {
                "example": {
                  "Result": "OK",
                  "Removed": 9012
                }
              }
            }
          },
          "400": {
            "description": "`Source` ist erforderlich"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "404": {
            "description": "Abmeldung nicht gefunden"
          }
        }
      }
    },
    "/history/list.{format}": {
      "get": {
        "tags": [
          "History"
        ],
        "operationId": "listHistory",
        "security": [
          {
            "OAuth2": [
              "email:read"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Versandverlauf auflisten",
        "description": "Gibt ein paginiertes Protokoll aller bisherigen E-Mail-Versendungen zurück.\nFiltern Sie nach Kampagnenkennung oder nach Betreff.\nSetzen Sie `bodyHTML=true`, um den HTML-Body einzuschließen (begrenzt automatisch auf 10 pro Seite).\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          },
          {
            "name": "subjectMessageFilter",
            "in": "query",
            "description": "Nach Kampagnenbetreff filtern (teilweise, Groß-/Kleinschreibung ignorierend)",
            "schema": {
              "type": "string"
            },
            "example": "newsletter"
          },
          {
            "name": "idCampaign",
            "in": "query",
            "description": "Nur den Verlauf einer bestimmten Kampagne zurückgeben",
            "schema": {
              "type": "integer"
            },
            "example": 8001
          },
          {
            "$ref": "#/components/parameters/numberOfRecords"
          },
          {
            "$ref": "#/components/parameters/pageNumber"
          },
          {
            "name": "bodyHTML",
            "in": "query",
            "description": "Auf `true` setzen, um den vollständigen HTML-Body einzuschließen.\nBegrenzt die Ergebnisse automatisch auf 10 pro Seite.\n",
            "schema": {
              "type": "boolean",
              "default": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Verlauf erfolgreich zurückgegeben",
            "content": {
              "application/json": {
                "example": {
                  "HistoricList": [
                    {
                      "IDHistoric": 9001,
                      "SubjectMessage": "Spring Newsletter — April 2026",
                      "DateSend": "2026-04-20T09:00:01",
                      "NumberSend": 4521,
                      "NumberOpen": 1823,
                      "NumberClick": 342
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/import/upload.{format}": {
      "post": {
        "tags": [
          "Import"
        ],
        "operationId": "uploadImportFile",
        "security": [
          {
            "OAuth2": [
              "contacts:write"
            ]
          },
          {
            "bearerAuth": []
          },
          {
            "IdClientHeader": [],
            "ApiKeyHeader": []
          },
          {
            "IdClientQuery": [],
            "ApiKeyQuery": []
          }
        ],
        "summary": "Kontaktdatei (CSV/XLSX) für den Massenimport hochladen",
        "description": "Laden Sie eine CSV- oder XLSX-Datei hoch, um E-Mail-Kontakte in eine Liste zu importieren.\nDie Datei wird gespeichert und zur asynchronen Verarbeitung in die Warteschlange gestellt — der Endpunkt gibt sofort eine `ImportJobId` zurück.\n\n**Anfragetyp:** `multipart/form-data`\n\n**Erforderliche Formularfelder:**\n- `IdClient` (Ganzzahl) — Ihre Mailpro-Kundenkennung\n- `ApiKey` (Zeichenkette) — Ihr API-Schlüssel\n- `ListId` (Ganzzahl) — Kennung der Zielliste. Der veraltete Alias `AddressBookId` wird ebenfalls akzeptiert.\n- `file` (Binärdaten) — die hochzuladende CSV- oder XLSX-Datei\n\n**Optional:**\n- `WebhookUrl` (Zeichenkette) — HTTPS-URL, die nach Abschluss der Verarbeitung aufgerufen wird.\n  Empfängt eine JSON-Nutzlast mit dem endgültigen Status (erfolgreich/fehlgeschlagen) und der Anzahl der importierten/übersprungenen/ungültigen Zeilen.\n\n**Dateiformat:**\n- `UTF-8`-kodiert\n- Erste Zeile = Kopfzeilen (eine davon muss `Email` lauten — Groß-/Kleinschreibung wird ignoriert)\n- Weitere Spalten werden auf benutzerdefinierte Felder der Zielliste abgebildet\n- Maximale Dateigröße: 50 MB\n",
        "parameters": [
          {
            "$ref": "#/components/parameters/format"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "ListId",
                  "file"
                ],
                "properties": {
                  "ListId": {
                    "type": "integer",
                    "description": "Kennung der Zielliste. Der veraltete Alias `AddressBookId` wird ebenfalls akzeptiert.",
                    "example": 101
                  },
                  "file": {
                    "type": "string",
                    "format": "binary",
                    "description": "CSV- oder XLSX-Datei (`UTF-8`, max. 50 MB)"
                  },
                  "WebhookUrl": {
                    "type": "string",
                    "format": "uri",
                    "description": "Callback-URL, die nach Abschluss der Verarbeitung aufgerufen wird",
                    "example": "https://example.com/hooks/mailpro-import"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Datei akzeptiert und in die Warteschlange gestellt",
            "content": {
              "application/json": {
                "example": {
                  "Result": "OK",
                  "ImportJobId": 13,
                  "InternalName": "230575-20260420140221-contacts.csv"
                }
              }
            }
          },
          "400": {
            "description": "Keine Datei hochgeladen oder fehlende ListId"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          },
          "500": {
            "description": "Server- oder Speicherfehler"
          }
        }
      }
    },
    "/webhooks": {
      "servers": [
        {
          "url": "https://webhook.mailpro.com/api/v2",
          "description": "Webhook-Verwaltungsdienst (getrennt vom Hauptserver der API)"
        }
      ],
      "get": {
        "summary": "Webhooks auflisten",
        "description": "Gibt alle für das authentifizierte Konto konfigurierten Webhooks zurück.",
        "tags": [
          "Webhooks"
        ],
        "responses": {
          "200": {
            "description": "Array von Webhooks",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookList"
                },
                "example": {
                  "items": [
                    {
                      "id": 14,
                      "url": "https://example.com/hooks/mailpro",
                      "description": "Slack-Integration",
                      "is_active": true,
                      "created_at": "2026-07-01T21:09:52.43",
                      "updated_at": "2026-07-21T18:56:08.02",
                      "last_delivery_at": "2026-07-21T18:56:07.653",
                      "last_delivery_status": 200,
                      "consecutive_failures": 0,
                      "events": [
                        "email.delivered",
                        "email.bounced"
                      ]
                    }
                  ],
                  "total": 1
                }
              }
            }
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      },
      "post": {
        "summary": "Webhook erstellen",
        "description": "Erstellt ein neues Webhook-Abonnement. Die Antwort enthält ein `secret`, das **nur einmal angezeigt** wird — speichern Sie es sofort serverseitig. Verwenden Sie es zur Überprüfung der HMAC-Signatur jeder eingehenden Nutzlast.\n\n**Grenzen**: max. 20 Webhooks pro Konto, max. 50 Ereignisse pro Webhook.\n",
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookCreate"
              },
              "example": {
                "url": "https://example.com/hooks/mailpro",
                "events": [
                  "email.delivered",
                  "email.bounced"
                ],
                "description": "Slack-Integration"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook erstellt — das `secret` wird nur hier zurückgegeben",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookCreateResponse"
                },
                "example": {
                  "id": 42,
                  "url": "https://example.com/hooks/mailpro",
                  "events": [
                    "email.delivered",
                    "email.bounced"
                  ],
                  "description": "Slack-Integration",
                  "isActive": true,
                  "consecutiveFailures": 0,
                  "autoDisabledAt": null,
                  "autoDisabledReason": null,
                  "createdAt": "2026-05-25T10:00:00Z",
                  "updatedAt": "2026-05-25T10:00:00Z",
                  "secret": "whsec_AbcD1234EfgH5678IjkL9012MnoP3456QrsT"
                }
              }
            }
          },
          "400": {
            "description": "Ungültige URL, ungültige Ereignisliste oder Limit überschritten"
          },
          "401": {
            "description": "Ungültige Zugangsdaten"
          }
        }
      }
    },
    "/webhooks/{id}": {
      "servers": [
        {
          "url": "https://webhook.mailpro.com/api/v2",
          "description": "Webhook-Verwaltungsdienst"
        }
      ],
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "integer",
            "format": "int64"
          }
        }
      ],
      "get": {
        "summary": "Webhook abrufen",
        "tags": [
          "Webhooks"
        ],
        "responses": {
          "200": {
            "description": "Der Webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "404": {
            "description": "Webhook nicht gefunden"
          }
        }
      },
      "put": {
        "summary": "Webhook aktualisieren",
        "description": "Teilaktualisierung — nur die übermittelten Felder werden geändert.",
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookUpdate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Aktualisierter Webhook",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Webhook"
                }
              }
            }
          },
          "400": {
            "description": "Ungültige Nutzlast"
          },
          "404": {
            "description": "Webhook nicht gefunden"
          }
        }
      },
      "delete": {
        "summary": "Webhook löschen",
        "description": "Löscht den Webhook und seinen gesamten Zustellverlauf dauerhaft.",
        "tags": [
          "Webhooks"
        ],
        "responses": {
          "204": {
            "description": "Gelöscht"
          },
          "404": {
            "description": "Webhook nicht gefunden"
          }
        }
      }
    },
    "/webhooks/{id}/test": {
      "servers": [
        {
          "url": "https://webhook.mailpro.com/api/v2",
          "description": "Webhook-Verwaltungsdienst"
        }
      ],
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "integer",
            "format": "int64"
          }
        }
      ],
      "post": {
        "summary": "Testereignis senden",
        "description": "Stellt ein sofortiges `ping`-Ereignis (oder jeden anderen Ereignistyp über das Body-Feld `eventType`) zur Zustellung an Ihren Endpunkt in die Warteschlange. Nützlich, um die Erreichbarkeit und die Signaturprüfung vor dem Einsatz für echte Ereignisse zu überprüfen.\n",
        "tags": [
          "Webhooks"
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "eventType": {
                    "type": "string",
                    "default": "ping"
                  }
                }
              },
              "example": {
                "eventType": "ping"
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Ereignis zur Zustellung in die Warteschlange gestellt",
            "content": {
              "application/json": {
                "example": {
                  "deliveryId": 1234,
                  "eventId": "evt_8f3a9b2c4d1e5f6789abcdef01234567",
                  "eventType": "ping"
                }
              }
            }
          },
          "404": {
            "description": "Webhook nicht gefunden"
          }
        }
      }
    },
    "/webhooks/{id}/rotate-secret": {
      "servers": [
        {
          "url": "https://webhook.mailpro.com/api/v2",
          "description": "Webhook-Verwaltungsdienst"
        }
      ],
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "integer",
            "format": "int64"
          }
        }
      ],
      "post": {
        "summary": "HMAC-Geheimnis rotieren",
        "description": "Generiert ein neues HMAC-Geheimnis und macht das alte sofort ungültig.\nDas neue Geheimnis wird in der Antwort **einmalig** zurückgegeben — speichern Sie es. Jede Zustellung wird ab diesem Zeitpunkt mit dem neuen Geheimnis signiert.\n\nVerwenden Sie diese Funktion, wenn Sie vermuten, dass Ihr Geheimnis kompromittiert wurde.\n",
        "tags": [
          "Webhooks"
        ],
        "responses": {
          "200": {
            "description": "Neues Geheimnis (einmalig sichtbar)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "secret": {
                      "type": "string"
                    }
                  }
                },
                "example": {
                  "secret": "whsec_XyzA9876BcdE5432FghI1098JklM7654NopQ"
                }
              }
            }
          },
          "404": {
            "description": "Webhook nicht gefunden"
          }
        }
      }
    },
    "/webhooks/{id}/deliveries": {
      "servers": [
        {
          "url": "https://webhook.mailpro.com/api/v2",
          "description": "Webhook-Verwaltungsdienst"
        }
      ],
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "integer",
            "format": "int64"
          }
        },
        {
          "in": "query",
          "name": "limit",
          "schema": {
            "type": "integer",
            "default": 50,
            "maximum": 200
          }
        },
        {
          "in": "query",
          "name": "cursor",
          "schema": {
            "type": "integer",
            "format": "int64"
          },
          "description": "Paginierungs-Cursor (= zuletzt gesehene Zustellungskennung). Gibt Zustellungen mit `id < cursor` zurück."
        }
      ],
      "get": {
        "summary": "Zustellversuche auflisten",
        "description": "Gibt den Verlauf der Zustellversuche für diesen Webhook zurück (30 Tage Aufbewahrung).\nNützlich für die Fehlersuche — welche Ereignisse gesendet wurden, welche Statuscodes empfangen wurden, Anzahl der Wiederholungen, Fehlermeldungen.\n",
        "tags": [
          "Webhooks"
        ],
        "responses": {
          "200": {
            "description": "Array von Zustellversuchen (neueste zuerst)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WebhookDelivery"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Webhook nicht gefunden"
          }
        }
      }
    },
    "/webhooks/{id}/deliveries/{deliveryId}/replay": {
      "servers": [
        {
          "url": "https://webhook.mailpro.com/api/v2",
          "description": "Webhook-Verwaltungsdienst"
        }
      ],
      "parameters": [
        {
          "in": "path",
          "name": "id",
          "required": true,
          "schema": {
            "type": "integer",
            "format": "int64"
          }
        },
        {
          "in": "path",
          "name": "deliveryId",
          "required": true,
          "schema": {
            "type": "integer",
            "format": "int64"
          }
        }
      ],
      "post": {
        "summary": "Zustellung wiederholen",
        "description": "Stellt einen neuen Zustellversuch mit derselben Nutzlast wie das Original in die Warteschlange.\nNützlich, um eine fehlgeschlagene Zustellung nach der Behebung Ihres Endpunkts erneut auszulösen.\nEs wird eine NEUE Zeile `Webhook_Delivery` erstellt (das Original wird zur Nachvollziehbarkeit aufbewahrt). Die Wiederholung durchläuft die Standard-Wiederholungsrichtlinie (gleicher Backoff-Zeitplan, gleiche automatische Deaktivierungsregel nach 10 Fehlschlägen).\n",
        "tags": [
          "Webhooks"
        ],
        "responses": {
          "202": {
            "description": "Wiederholung in die Warteschlange gestellt",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "new_delivery_id": {
                      "type": "integer",
                      "format": "int64",
                      "example": 12999
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Webhook oder Zustellung nicht gefunden"
          }
        }
      }
    }
  }
}