Zur Dokumentation springen
CLI

E-Mails senden und verfolgen

Mail mit den `emails`-Befehlen senden, gebündelt senden, übersetzen, planen und abbrechen, und dann mit `tracking` ihre Zustellung, Öffnungen und Klicks verfolgen.

Überblick

Der Namespace emails ist die Versand-API als Befehle, einer für jede Methode von openemail.emails im SDK. Jeder ruft einen Endpunkt auf und gibt aus, was dieser zurückgibt. Der Namespace tracking liest die Öffnungen und Klicks auf die Mail, die Sie gesendet haben. openemail email funktioniert anstelle von openemail emails.

Jeder Befehl hier braucht eine Anmeldung, über den Browser oder mit einem API-Schlüssel, und einen von zwei Scopes: emails:send zum Senden, Übersetzen, Abbrechen und Umplanen, und emails:read für alles, was nur liest.

Welcher Versand der richtige ist

openemail send ist der handgeschriebene Befehl von der Seite Mail, und er sendet über emails send. Er ist für eine Person am Terminal gemacht: Er wählt die Absenderadresse, wenn Sie --from weglassen, liest den Body aus einer Datei, von stdin oder aus Ihrem Editor, hängt Dateien über ihren Pfad an und zeigt eine Zusammenfassung zur Bestätigung, bevor irgendetwas hinausgeht. openemail emails send nimmt den Request-Body als Flags, eines für jedes Feld, und fragt nichts, was zu einem Skript passt, das genau weiß, was es sendet.

sendemails send
--from <address>Pflicht, wie --to, außer --data enthält es. send kann es weglassen und eine Adresse für Sie wählen
-f, --body-file <path>Kein Datei-Flag für den Body. Übergeben Sie --html "$(cat body.html)" oder die ganze Anfrage in --data @email.json
-a, --attach <path>--attachments, ein JSON-Array von Dateien, jede mit einem filename und base64-content oder mit der fileId einer Datei, die schon in Dateien liegt
--at <when>--scheduled-at <when>, ein ISO-8601-Zeitpunkt oder eine Dauer wie PT1H oder P2D. send nimmt auch kurze Verzögerungen wie 10m, 2h und 1d
--undo <seconds>--cancellable-for-seconds <n>, von 0 bis 900
--translate <language>--translate '{"to":"de"}', das auch from, includeOriginal und subject nimmt
--template <id> --props <json>--template '{"id":"welcome","props":{"name":"Ada"}}', das auch eine version festlegen kann
--draft <id>--draft-id <id>
--thread <id>--thread-id <id>
--tag <key=value>--tags <key=value>, wiederholt, oder ein JSON-Objekt

Nur emails send hat --tracking, um Öffnungen oder Klicks für einen Versand abzuschalten, --signature, --headers für eigene Header, --attachment-delivery, um zwischen dem Anhängen von Dateien und dem Verlinken zu wählen, und --data für den ganzen Body als JSON, inline, aus einer Datei mit @path oder von stdin mit -.

Die beiden enden unterschiedlich. send endet mit Exit-Code 1, wenn die E-Mail als failed zurückkommt. emails send endet mit Exit-Code 0, sobald die API geantwortet hat, prüfen Sie also status in der Ausgabe.

Jeder emails-Befehl

send, send-batch, translate, cancel und reschedule brauchen emails:send. list, get, list-events und get-tracking brauchen emails:read. Eine E-Mail-ID ist msg_ gefolgt von 24 Hexzeichen, so wie ein Versand sie zurückgibt.

BefehlWas es tut
openemail emails send --from <value> --to <a,b>Eine E-Mail sofort senden, mit --cancellable-for-seconds für ein Rückgängig-Fenster zurückhalten oder mit --scheduled-at planen. Der Body ist --html, --text oder beides, eine gespeicherte --template oder eine gespeicherte --draft-id
openemail emails send-batch <emails>Bis zu 100 unabhängige E-Mails in einer Anfrage senden, aus einem JSON-Array in einer Datei, inline oder über stdin mit -. Jeder Eintrag hat die Form des Bodys von emails send und gelingt oder scheitert für sich
openemail emails translate --to <value>Vorschau dessen, was ein übersetzter Versand zustellen würde, für --subject, --html oder --text. Nichts wird gespeichert oder gesendet, und es verbraucht eine KI-Aktion
openemail emails listEine Seite gesendeter E-Mails, neueste zuerst, eingegrenzt mit --status, --from oder --broadcast-id
openemail emails get <id>Eine gesendete E-Mail mit Status, Fehler und Zustellzeit jedes einzelnen Empfängers, und dem vollständigen Tracking-Bericht, wenn sie getrackt wurde
openemail emails list-events <id>Die Ereigniskette eines Versands, älteste zuerst: angenommen, geplant, gesendet, zugestellt, gebounct, beschwert, geöffnet, geklickt und die übrigen
openemail emails get-tracking <id>Der Interaktionsbericht eines Versands: seine Summen, ein Eintrag pro getrackter Kopie und jeder umgeschriebene Link mit seinen Klicks
openemail emails cancel <id>Eine E-Mail in der Warteschlange oder eine geplante E-Mail stoppen, bevor sie hinausgeht. Fragt nach einer Bestätigung
openemail emails reschedule <id> <scheduled-at>Eine E-Mail in der Warteschlange oder eine geplante E-Mail auf einen ISO-8601-Zeitpunkt verschieben, oder um eine Dauer wie PT30M, von einer Sekunde bis 365 Tage in die Zukunft

Jeder tracking-Befehl

Alle fünf brauchen emails:read. tracking get, list-opens und list-clicks nehmen jede der beiden IDs einer Nachricht: die msg_-ID, die ihr Versand zurückgegeben hat, oder die tmsg_-Tracking-ID, die tracking list und Webhook-Payloads enthalten.

BefehlWas es tut
openemail tracking listEine Seite getrackter Nachrichten, die in einem Zeitraum gesendet wurden, neueste zuerst, jede mit ihrem vollständigen Bericht. --opened und --clicked grenzen sie ein, und --no-opened behält die, die niemand geöffnet hat. Der Zeitraum beträgt 30 Tage, sofern --days oder --minutes nichts anderes sagt
openemail tracking get-statsDie Zahlen hinter einem Interaktionsbereich: getrackte, geöffnete und geklickte Nachrichten, Öffnungs- und Klickraten, eine Zeitreihe in --grain-Intervallen und die häufigsten Links, Mail-Clients und Länder
openemail tracking get <id>Der Interaktionsbericht einer Nachricht, dasselbe Dokument, das emails get-tracking zurückgibt
openemail tracking list-opens <id>Die einzelnen Öffnungen hinter der Öffnungszahl einer Nachricht, neueste zuerst, jede als human, proxy oder machine markiert. --include-machine fügt die Zugriffe hinzu, die nicht gezählt wurden
openemail tracking list-clicks <id>Die einzelnen Klicks auf die Links einer Nachricht, neueste zuerst, jeweils mit der ursprünglichen url. --include-machine fügt Link-Scanner und zusammengefasste Wiederholungen hinzu

tracking list und get-stats umfassen jede getrackte Nachricht, die das Postfach gesendet hat, einschließlich Mail, die in der Web-App geschrieben wurde, und Mail, die von den MCP-Tools oder dem Assistenten gesendet wurde, während emails list die Versanddatensätze enthält, die die API angelegt hat. Ein Bericht ohne Versanddatensatz hat sendId auf null gesetzt.

Beispiele

Aus einem Skript mit einem eigenen Idempotency-Key senden. Ein erneuter Lauf mit demselben --idempotency-key gibt die erste E-Mail mit replayed: true aus, statt eine zweite zu senden.

Aus einem Skript senden
openemail emails send \  --from 'Acme Billing <[email protected]>' \  --to [email protected] \  --subject 'Your September invoice' \  --html '<p>The invoice is attached. Tell me if anything on it looks wrong.</p>' \  --attachments '[{"fileId":"file_6bb640f5b99e47deb758f1f5"}]' \  --tracking '{"opens":false}' \  --idempotency-key invoice:inv_2026_09_4192 \  --json | jq -r '.id + " " + .status'

Lassen Sie eine Person eine Übersetzung lesen, bevor sie hinausgeht. Senden Sie den freigegebenen Wortlaut als einfaches --subject und --html, ohne --translate, sonst wird er ein zweites Mal übersetzt. Das übersetzte html enthält Ihr Original bereits darunter, außer Sie übergeben --no-include-original.

Übersetzung prüfen, dann senden
openemail emails translate --to de \  --subject 'Your September invoice' \  --html "$(cat invoice.html)" \  --json > preview.jsonjq -r .html preview.jsonopenemail emails send --from [email protected] --to [email protected] \  --subject "$(jq -r .subject preview.json)" \  --html "$(jq -r .html preview.json)"

Einen Batch aus einer Datei senden. Der Befehl endet mit Exit-Code 0, sobald der Batch verarbeitet wurde, auch wenn einige Einträge gescheitert sind, lesen Sie also failed und den status jedes Eintrags. Ein erneuter Lauf mit demselben Schlüssel spielt die Einträge, die hinausgegangen sind, erneut ab und sendet nur den Rest, solange das Array seine Reihenfolge behält.

receipts.json
[  { "from": "[email protected]", "to": "[email protected]", "subject": "Receipt 4192", "text": "Thanks for your order." },  { "from": "[email protected]", "to": "[email protected]", "subject": "Receipt 4193", "text": "Thanks for your order." }]
Den Batch senden
openemail emails send-batch receipts.json --idempotency-key receipts:2026-09-27 --json > result.jsonjq '{ sent, failed }' result.jsonjq -r '.items[] | select(.status == "error") | "\(.index) \(.error.code)"' result.json

Eine E-Mail planen, verschieben und abbrechen. --yes beantwortet die Bestätigung, nach der cancel fragt, was ein Skript nicht kann.

Planen, verschieben und abbrechen
ID=$(openemail send --from [email protected] --to [email protected] --subject "Standup notes" \  --body-file notes.md --at 2026-10-01T09:00:00Z --json | jq -r .id)openemail emails reschedule "$ID" 2026-10-01T13:00:00Zopenemail emails get "$ID" --json | jq -r '.status + " " + .scheduledAt'openemail emails cancel "$ID" --yes

Die gescheiterten Versände finden und nachlesen, was mit einem davon passiert ist. Weitergeleitet ohne --json gibt --all ein JSON-Objekt pro Zeile aus.

Gescheiterte Versände finden
openemail emails list --status failed,partial --from [email protected] --all | jq -r .idopenemail emails get msg_3f9a1c07d2b84e6a9c5b1f20openemail emails list-events msg_3f9a1c07d2b84e6a9c5b1f20 --all --json | jq -r '.items[] | .createdAt + " " + .type'

Eine Woche Interaktionen in Tagen lesen, die um Mitternacht UTC+2 wechseln, auflisten, was niemand geöffnet hat, und die Klicks auf jeden Link einer Nachricht zählen.

Eine Woche Öffnungen und Klicks
openemail tracking get-stats --days 7 --offset-minutes 120 --json | jq '{ tracked, openRate, clickRate }'openemail tracking list --no-opened --days 7 --all | jq -r .subjectopenemail tracking list-clicks msg_3f9a1c07d2b84e6a9c5b1f20 --all | jq -r .url | sort | uniq -c

Scopes, Codes und Bestätigungen

  • Eine Browser-Anmeldung fragt auf der Freigabeseite nach Scopes, und openemail login --scopes emails:send,emails:read wählt beide vor. Ein Befehl, dessen Scope fehlt, bricht mit Exit-Code 4 und insufficient_scope ab und nennt den Scope.
  • send --attach mit mehr als 5 MB an Dateien lädt sie zuerst in Dateien hoch, was zusätzlich files:write braucht.
  • Keiner dieser Befehle fragt nach einem Bestätigungscode, eine Browser-Anmeldung führt sie also genauso aus wie ein API-Schlüssel.
  • emails cancel fragt nach, bevor es abbricht, und --yes antwortet für Sie. Unbeaufsichtigt ohne --yes bricht es mit Refusing to run unattended. Pass --yes to confirm. und Exit-Code 2 ab.
  • emails send, send-batch und reschedule fragen nie. send zeigt eine Zusammenfassung und fragt nur in einem Terminal, und --yes überspringt auch das.
  • --dry-run gibt die Anfrage aus, die ein Befehl senden würde, sendet nichts und endet mit Exit-Code 0. Bei emails translate verbraucht das keine KI-Aktion, und bei emails cancel fragt es nichts.

Ergebnisseiten

emails list, emails list-events, tracking list, list-opens und list-clicks lesen eine Seite. --limit legt ihre Größe fest, von 1 bis 100 mit 25 als Standard für die beiden emails-Listen und von 1 bis 200 mit 50 als Standard für die drei tracking-Listen. --cursor macht beim Cursor weiter, den eine Seite ausgegeben hat.

  • --all liest jede Seite und streamt die Einträge: eine Tabelle in einem Terminal und ein JSON-Objekt pro Zeile, wenn weitergeleitet oder mit --ndjson.
  • --max <n> hört nach so vielen Einträgen auf und schließt --all ein.
  • --json gibt ein einziges { items, hasMore, nextCursor }-Dokument aus, auch mit --all.
  • Geblättert wird per Cursor, nicht per Offset, sodass Mail, die während des Blätterns gesendet wird, nie eine Zeile verschiebt oder wiederholt.

Gut zu wissen

  • Jeder Lauf erzeugt seinen eigenen Idempotency-Key, der die Wiederholungen innerhalb dieses Laufs abdeckt. Ein zweimal ausgeführter Versand sendet zweimal, außer beide Läufe übergeben denselben --idempotency-key. Derselbe Schlüssel mit einem anderen Body wird mit idempotency_key_reuse und Exit-Code 7 abgelehnt.
  • Nur Mail mit queued und scheduled lässt sich abbrechen oder verschieben. Ein sofortiger Versand ohne Rückgängig-Fenster geht innerhalb der Anfrage hinaus, wenn Sie seine ID in der Hand haben, ist es also meist zu spät, und der Aufruf endet mit email_not_cancellable und Exit-Code 6.
  • Eine abgebrochene E-Mail bleibt abgebrochen. Umplanen ändert nur die Zeit, bei einer Dauer ab dem Moment gerechnet, in dem der Server die Anfrage erhält. Um den Text zu ändern, brechen Sie also ab und senden erneut.
  • Eine Übersetzung, die sich nicht erstellen lässt, lässt den ganzen Versand scheitern, und nichts geht unübersetzt hinaus. Ein übersetzter Batch enthält höchstens 10 Nachrichten mit translate.
  • Ein aufgebrauchtes Versandkontingent stoppt einen Versand mit send_quota_exceeded bis zum Monatsersten, und ein aufgebrauchtes KI-Kontingent stoppt eine Übersetzung mit ai_quota_exceeded bis Mitternacht UTC, beide mit Exit-Code 8.
  • Mail, die mit einem oe_test_-Schlüssel gesendet wurde, wird nie zugestellt. Sie steht auf sent, mit transport auf test, und wird nie getrackt.
  • emails get-tracking und tracking get antworten mit 404, Exit-Code 5, für eine Nachricht ohne Pixel und ohne umgeschriebenen Link, denn nicht getrackt ist nicht dasselbe wie nicht geöffnet. Das Tracking folgt der Einstellung, mit der die Nachricht gesendet wurde, späteres Einschalten erreicht frühere Mail also nicht.
  • Jede Zahl ist eine Untergrenze. Ein Leser, dessen Mail-Client Bilder blockiert, zählt nie als Öffnung, und ein Klick ist ein stärkerer Beleg fürs Lesen als eine Öffnung.
  • list-opens und list-clicks antworten mit 404 für eine msg_-ID ohne Tracking, nehmen eine tmsg_-ID aber so, wie sie ist, eine unbekannte kommt also als leere Liste zurück.
  • Ein Schlüssel, der auf einige Adressen beschränkt ist, sieht nur die Mail, die von diesen Adressen gesendet wurde, und einer, der eine ganze Domain umfasst, deckt jede Adresse darauf ab.

Jedes Flag

Diese Seite nennt die wichtigsten Flags. openemail <command> --help listet jedes Argument und Flag eines Befehls mit seinem Typ, dem nötigen Scope, Methode und Pfad, dem Rückgabewert und den Hinweisen aus der API-Referenz. Fügen Sie --json hinzu, um dieselbe Hilfe als ein JSON-Dokument zu erhalten.

Terminal
openemail emails --helpopenemail emails send --helpopenemail tracking list-opens --help --json

Der Posteingang,
nach eigenen Regeln.

E-Mail-Infrastruktur für Unternehmen, KI, Agenten und persönliche E-Mail. Gebaut für Skalierung, Privatsphäre und Kontrolle. Alles, was E-Mail vom ersten Tag an hätte haben sollen.

OpenEmail

E-Mail-Infrastruktur für Unternehmen, KI, Agenten und persönliche E-Mail. Gebaut für Skalierung, Privatsphäre und Kontrolle. Alles, was E-Mail vom ersten Tag an hätte haben sollen.

© 2026 OpenEmail. Alle Rechte vorbehalten.