Dokumentation
Es gibt zwei Wege, eine Nachricht einzuliefern. Beide führen durch dieselbe Verarbeitung — Signatur, Warteschlange, Zustellung und das Löschen des Inhalts danach sind identisch.
Die HTTP-API ist der direktere Weg. Ein Aufruf, eine Antwort mit einer Nachrichten-ID, keine Verbindungsverwaltung.
SMTP ist für Software gedacht, die Sie nicht ändern können: WordPress, ein ERP, ein Drucker, ein Monitoring-System. Sie tragen Zugangsdaten ein, sonst nichts.
Wenn Sie die Wahl haben, nehmen Sie die HTTP-API. Sie meldet Fehler sofort und verständlich; SMTP kann nur dreistellige Codes.
Bevor Sie senden können
1. Domain hinzufügen
Im Dashboard unter Domains. Sie senden nur von Domains, die Ihnen gehören — das ist keine Schikane, sondern die Voraussetzung dafür, dass Empfänger Ihre Nachrichten annehmen.
2. DNS-Einträge setzen
Nach dem Hinzufügen zeigt das Dashboard drei Einträge. Tragen Sie sie bei Ihrem DNS-Anbieter ein:
| Typ | Wofür |
| --- | --- |
| TXT auf <selektor>._domainkey.<ihre-domain> | DKIM — signiert Ihre Nachrichten |
| TXT auf <ihre-domain> | SPF — erlaubt uns den Versand in Ihrem Namen |
| MX auf bounce.<ihre-domain> | nimmt Unzustellbarkeitsmeldungen entgegen |
Die genauen Werte stehen im Dashboard; sie sind für jede Domain verschieden.
DNS-Änderungen brauchen je nach Anbieter einige Minuten bis Stunden. Die Verifizierung im Dashboard prüft auf Knopfdruck.
3. API-Key erzeugen
Unter API-Keys. Der Schlüssel wird genau einmal angezeigt — wir speichern ihn nicht im Klartext und können ihn nicht erneut zeigen. Verlorene Schlüssel werden widerrufen und ersetzt, nicht wiederhergestellt.
Achten Sie auf die Berechtigungen: Zum Senden genügt emails:send. Ein
Schlüssel, der in einer Anwendung liegt, sollte nicht mehr dürfen als diese
Anwendung braucht.
Weg 1: HTTP-API
curl -X POST https://api.mittaro.de/v1/emails \
-H "Authorization: Bearer tx_live_IHR_SCHLUESSEL" \
-H "Content-Type: application/json" \
-d '{
"from": "rechnung@ihre-domain.de",
"to": "kundin@example.com",
"subject": "Ihre Rechnung 2026-0815",
"text": "Guten Tag,\n\nanbei Ihre Rechnung.\n\nViele Grüße"
}'
Die Antwort:
{ "id": "email_01JQ8ZK3M2N4P6R8T0V2X4Y6", "status": "queued" }
202 heißt angenommen und eingereiht. Die id ist Ihre Referenz — sie steht in
der Nachrichtenliste im Dashboard und in jeder späteren Auskunft über diese
Nachricht.
Felder
| Feld | Pflicht | Anmerkung |
| --- | --- | --- |
| from | ja | Muss zu einer verifizierten Domain gehören |
| to | ja | Adresse oder Liste von Adressen |
| subject | ja | |
| text | einer von beiden | Nur-Text-Fassung |
| html | einer von beiden | HTML-Fassung |
| cc, bcc | nein | |
| reply_to | nein | |
| headers | nein | Eigene Header, aber nur aus der Liste unten |
Geben Sie nach Möglichkeit beides an, text und html. Eine reine
HTML-Nachricht ohne Textfassung wird von Spamfiltern schlechter bewertet, und
manche Empfänger lesen ohnehin nur Text.
Andere als die genannten Felder werden abgelehnt, nicht ignoriert — die Antwort nennt das Feld, das stört.
Anhänge
Anhänge sind derzeit nicht möglich, weder über die API noch über SMTP. Eine
Nachricht mit attachments bekommen Sie als 422 zurück. Wir stellen sie nicht
ohne den Anhang zu, denn dann hielten Sie die Rechnung für versendet, die daran
hing.
Der Grund ist nicht, dass es noch niemand gebaut hätte. Anhänge bringen pro Feature den größten Zuwachs an Angriffs- und Datenschutzfläche: fremde Dateien, die wir entgegennehmen, speichern und weiterreichen. Das wollen wir erst anbieten, wenn Malware-Prüfung, verschlüsselte Ablage, harte Größen- und Typgrenzen und die garantierte Löschung stehen — und zwar so, dass die Prüfung bei uns läuft und nicht bei einem Scan-Dienst, dem wir Ihre Dateien schicken.
Diese Anforderungen liegen fest, das Feature ist geplant. Einen Termin nennen wir bewusst nicht, solange er nicht sicher ist.
Bis dahin: Legen Sie die Datei in Ihrem System ab und verlinken Sie sie in der Nachricht. Für Rechnungen und Belege ist das ohnehin oft die bessere Lösung — der Link kann Zugriff verlangen, der Anhang liegt für immer unverschlüsselt in irgendeinem Postfach.
Bilder per URL, und was dabei zu bedenken ist
Ein <img src="https://…"> in Ihrem HTML geht durch — wir sanitisieren nichts
und schreiben keine Links um. Die Datei reist dabei aber nicht mit, sondern wird
vom Mailprogramm der Empfängerin nachgeladen. Das hat zwei Folgen, die Sie
kennen sollten.
Externe Bilder werden meist nicht automatisch geladen. Gmail, Outlook und Apple Mail blockieren sie hinter „Bilder anzeigen". Ihre Nachricht muss also auch ohne Bilder vollständig lesbar sein.
Der ausliefernde Server sieht den Abruf — mit Zeitpunkt, IP-Adresse und
Mailprogramm der Empfängerin. Technisch ist das dasselbe wie ein Zählpixel, nur
auf Ihrem Server statt auf unserem. Wir messen keine Öffnungen; ob Sie es tun,
entscheiden Sie mit dieser Wahl selbst. Wenn Sie es nicht wollen: Liefern Sie
Bilder unter einer URL aus, die für alle Empfänger identisch ist. Eine je
Nachricht eindeutige URL — logo.png?id=… — macht aus dem Bild eine
Öffnungsmessung, auch wenn sie nicht so gemeint war.
Eigene Header
Zulässig sind genau diese fünf, höchstens zehn Stück je Nachricht:
| Header | Wofür |
| --- | --- |
| X-Entity-Ref-ID | Ihre eigene Referenz, etwa eine Bestellnummer |
| In-Reply-To | Zuordnung zu einer vorangegangenen Nachricht |
| References | Einordnung in einen Nachrichtenverlauf |
| List-Unsubscribe | Abmeldeweg, den der Mailclient anbietet |
| List-Unsubscribe-Post | Abmeldung mit einem Klick, ohne Rückfrage |
Alles andere lehnen wir ab. Das ist eine bewusst kurze Liste: Header wie Bcc,
Return-Path, Received oder DKIM-Signature würden den Versand unterlaufen
oder eine Signatur vortäuschen, und eine Sperrliste müsste jede solche
Möglichkeit im Voraus kennen. Fehlt Ihnen ein Header, schreiben Sie uns — die
Liste ist erweiterbar, nur eben von Hand.
Doppelte Sendungen vermeiden
Setzen Sie den Header Idempotency-Key auf einen Wert, der die Nachricht
eindeutig macht — etwa Ihre Rechnungsnummer:
-H "Idempotency-Key: rechnung-2026-0815"
Wiederholen Sie den Aufruf mit demselben Schlüssel, antworten wir mit 200 und
derselben id, ohne ein zweites Mal zu senden. Das ist der Unterschied zwischen
einem Wiederholungsversuch nach einem Netzwerkfehler und zwei Rechnungen im
Postfach Ihrer Kundin.
Fehler
| Code | Bedeutung |
| --- | --- |
| 202 | Angenommen |
| 200 | Angenommen, war aber schon bekannt (Idempotency-Key) |
| 400 | Der Aufruf selbst ist kaputt — etwa ein zu langer Idempotency-Key |
| 401 | Schlüssel fehlt, ist falsch oder widerrufen |
| 403 | Der Schlüssel darf das nicht, oder die Domain ist nicht verifiziert |
| 409 | Derselbe Idempotency-Key für eine andere Nachricht |
| 413 | Der Rumpf ist zu groß |
| 422 | Der Aufbau stimmt nicht — die Antwort nennt das Feld |
| 429 | Kontingent erreicht. Retry-After nennt die Wartezeit in Sekunden |
| 503 | Vorübergehend nicht verfügbar. Später erneut versuchen |
Bei 4xx außer 429 hilft ein Wiederholungsversuch nicht — die Ursache liegt
im Aufruf. Bei 429 und 503 warten Sie die genannte Zeit ab.
Weg 2: SMTP
Für Software, die nur SMTP spricht. Die Zugangsdaten:
| Feld | Wert |
| --- | --- |
| Server | smtp.mittaro.de |
| Port | 587 (STARTTLS) oder 465 (implizites TLS) |
| Verschlüsselung | erforderlich |
| Benutzername | apikey |
| Passwort | Ihr API-Key, also tx_live_… |
Der Benutzername ist wörtlich apikey — für alle Kunden gleich. Er trägt keine
Information; Ihr Schlüssel allein bestimmt, für wen gesendet wird.
Ohne TLS keine Anmeldung. Der Server bietet AUTH erst nach STARTTLS an.
Ein API-Key ist ein vollwertiger Sendezugang und hat im Klartext nichts im Netz
verloren.
Beispiel: Node.js
import nodemailer from "nodemailer";
const transport = nodemailer.createTransport({
host: "smtp.mittaro.de",
port: 587,
requireTLS: true,
auth: { user: "apikey", pass: process.env.MITTARO_KEY },
});
await transport.sendMail({
from: "rechnung@ihre-domain.de",
to: "kundin@example.com",
subject: "Ihre Rechnung 2026-0815",
text: "Guten Tag, anbei Ihre Rechnung.",
});
Beispiel: WordPress
Mit einem SMTP-Plugin Ihrer Wahl. Tragen Sie die Werte aus der Tabelle oben ein
und setzen Sie die Absenderadresse auf eine Adresse Ihrer verifizierten Domain.
Der häufigste Fehler ist eine Absenderadresse, die noch auf @gmail.com oder
den Hoster zeigt — die wird abgelehnt.
Beispiel: PHP
$mail->isSMTP();
$mail->Host = 'smtp.mittaro.de';
$mail->Port = 587;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->SMTPAuth = true;
$mail->Username = 'apikey';
$mail->Password = getenv('MITTARO_KEY');
Was der Server antwortet
| Code | Bedeutung |
| --- | --- |
| 250 Ok: queued as email_… | Angenommen, mit Ihrer Nachrichten-ID |
| 450 | Kontingent erreicht — später erneut versuchen |
| 451 | Bei uns klemmt es gerade — später erneut versuchen |
| 550 | Endgültig abgelehnt, der Text nennt den Grund |
550 bleibt 550: Eine unverifizierte Absenderdomain melden wir nicht als
vorübergehenden Fehler. Sonst versucht Ihr Mailserver es tagelang, die Nachricht
hängt in seiner Warteschlange, und Sie erfahren den eigentlichen Grund nie.
Grenzen des SMTP-Wegs
Der SMTP-Weg kann nicht mehr als die HTTP-API — das ist Absicht, es gibt keinen zweiten Verarbeitungspfad.
- Anhänge werden abgelehnt, wie über die API auch — siehe den Abschnitt
„Anhänge" oben. Das gilt zusätzlich für eingebettete Bilder (
cid:): Für die Verarbeitung sind das Anhänge, auch wenn im Postfach nur ein Logo zu sehen wäre. Binden Sie Bilder über eine absolutehttps:-URL ein — siehe den Abschnitt „Bilder per URL" oben, er nennt auch die Nebenwirkungen. - Eigene Header werden nicht übernommen. Ein eingeliefertes MIME trägt Dutzende Header, die zur Zustellung gehören; unsere Verarbeitung setzt sie selbst. Wer eigene Header braucht, nimmt die HTTP-API — dort im Rahmen der Liste im Abschnitt „Eigene Header".
- Reine Blindkopie-Nachrichten werden abgelehnt. Ohne sichtbaren Empfänger
in
TooderCcmüssten wir eine Bcc-Adresse sichtbar machen, um die Nachricht zu bauen. Das tun wir nicht. - Kein Idempotency-Key. SMTP kennt kein Gegenstück dazu.
Was wir nicht tun
Kein Öffnungs- und Klick-Tracking. Wir bauen keine Zählpixel ein und schreiben keine Links um. Ihre Empfänger haben dem nicht zugestimmt, und für transaktionale Post braucht es das nicht.
Kein Zugriff auf Inhalte über die API. Betreff, Text und HTML lassen sich nicht auslesen — auch nicht von Ihnen, auch nicht mit gültigem Schlüssel. Ein gestohlener Schlüssel wird damit vom Sendezugang nicht zum Leserecht auf Ihre gesamte Korrespondenz.
Keine dauerhafte Speicherung von Inhalten. Der Inhalt wird nach der Zustellung gelöscht, in derselben Datenbanktransaktion. Was bleibt, sind Metadaten für die Nachvollziehbarkeit.