Aller à la documentation
CLI

Envoyer et suivre des e-mails

Envoyez, envoyez par lots, traduisez, programmez et annulez du courrier avec les commandes `emails`, puis suivez sa livraison, ses ouvertures et ses clics avec `tracking`.

Vue d'ensemble

L'espace de noms emails est l'API d'envoi sous forme de commandes, une pour chaque méthode de openemail.emails dans le SDK. Chacune appelle un point de terminaison et affiche ce qu'il renvoie. L'espace de noms tracking lit les ouvertures et les clics sur le courrier que vous avez envoyé. openemail email fonctionne à la place de openemail emails.

Chaque commande ici a besoin d'une connexion, par le navigateur ou par une clé API, et de l'un de deux scopes : emails:send pour envoyer, traduire, annuler et reprogrammer, et emails:read pour tout ce qui ne fait que lire.

Quel envoi utiliser

openemail send est la commande écrite à la main de la page Courrier, et elle envoie via emails send. Elle est faite pour une personne au terminal : elle choisit l'adresse d'envoi quand vous omettez --from, lit le corps depuis un fichier, stdin ou votre éditeur, joint des fichiers par leur chemin et affiche un récapitulatif à confirmer avant que quoi que ce soit ne parte. openemail emails send prend le corps de la requête en options, une pour chaque champ, et ne demande rien, ce qui convient à un script qui sait exactement ce qu'il envoie.

sendemails send
--from <address>Obligatoire, comme --to, sauf si --data le contient. send peut l'omettre et choisir une adresse pour vous
-f, --body-file <path>Pas d'option de fichier pour le corps. Passez --html "$(cat body.html)", ou toute la requête dans --data @email.json
-a, --attach <path>--attachments, un tableau JSON de fichiers, chacun avec un filename et un content en base64, ou avec le fileId d'un fichier déjà présent dans Fichiers
--at <when>--scheduled-at <when>, un instant ISO 8601 ou une durée comme PT1H ou P2D. send accepte aussi des délais courts comme 10m, 2h et 1d
--undo <seconds>--cancellable-for-seconds <n>, de 0 à 900
--translate <language>--translate '{"to":"de"}', qui accepte aussi from, includeOriginal et subject
--template <id> --props <json>--template '{"id":"welcome","props":{"name":"Ada"}}', qui peut aussi fixer une version
--draft <id>--draft-id <id>
--thread <id>--thread-id <id>
--tag <key=value>--tags <key=value>, répétée, ou un objet JSON

Seule emails send a --tracking pour désactiver les ouvertures ou les clics sur un envoi, --signature, --headers pour des en-têtes personnalisés, --attachment-delivery pour choisir entre joindre les fichiers et les lier, et --data pour tout le corps en JSON, en ligne, depuis un fichier avec @path ou depuis stdin avec -.

Les deux se terminent différemment. send sort avec le code 1 quand l'e-mail revient failed. emails send sort avec le code 0 dès que l'API a répondu, vérifiez donc status dans ce qu'elle affiche.

Chaque commande emails

send, send-batch, translate, cancel et reschedule ont besoin de emails:send. list, get, list-events et get-tracking ont besoin de emails:read. Un identifiant d'e-mail est msg_ suivi de 24 caractères hexadécimaux, tel qu'un envoi le renvoie.

CommandeCe qu'il fait
openemail emails send --from <value> --to <a,b>Envoyer un e-mail maintenant, le retenir pendant une fenêtre d'annulation avec --cancellable-for-seconds, ou le programmer avec --scheduled-at. Le corps est --html, --text ou les deux, un --template enregistré, ou un --draft-id enregistré
openemail emails send-batch <emails>Envoyer jusqu'à 100 e-mails indépendants en une requête, depuis un tableau JSON dans un fichier, en ligne, ou sur stdin avec -. Chaque élément a la forme du corps de emails send et réussit ou échoue de son côté
openemail emails translate --to <value>Prévisualiser ce qu'un envoi traduit livrerait, pour --subject, --html ou --text. Rien n'est enregistré ni envoyé, et cela consomme une action d'IA
openemail emails listUne page d'e-mails envoyés, du plus récent au plus ancien, filtrée par --status, --from ou --broadcast-id
openemail emails get <id>Un e-mail envoyé avec le statut, l'erreur et l'heure de livraison propres à chaque destinataire, et le rapport de suivi complet quand il a été suivi
openemail emails list-events <id>La suite d'événements d'un envoi, du plus ancien au plus récent : accepté, programmé, envoyé, livré, rebondi, plainte, ouvert, cliqué et les autres
openemail emails get-tracking <id>Le rapport d'engagement d'un envoi : ses totaux, une entrée par copie suivie, et chaque lien réécrit avec ses clics
openemail emails cancel <id>Arrêter un e-mail en file d'attente ou programmé avant son départ. Demande confirmation
openemail emails reschedule <id> <scheduled-at>Déplacer un e-mail en file d'attente ou programmé à un instant ISO 8601, ou d'une durée comme PT30M, d'une seconde à 365 jours dans le futur

Chaque commande tracking

Les cinq ont besoin de emails:read. tracking get, list-opens et list-clicks acceptent l'un ou l'autre des identifiants d'un message : l'identifiant msg_ renvoyé par son envoi, ou l'identifiant de suivi tmsg_ que portent tracking list et les payloads de webhook.

CommandeCe qu'il fait
openemail tracking listUne page de messages suivis envoyés sur une période, du plus récent au plus ancien, chacun avec son rapport complet. --opened et --clicked la filtrent, et --no-opened garde ceux que personne n'a ouverts. La période est de 30 jours sauf si --days ou --minutes indique autre chose
openemail tracking get-statsLes chiffres derrière un panneau d'engagement : messages suivis, ouverts et cliqués, taux d'ouverture et de clic, une série temporelle par tranches --grain, et les principaux liens, clients mail et pays
openemail tracking get <id>Le rapport d'engagement d'un message, le même document que renvoie emails get-tracking
openemail tracking list-opens <id>Les ouvertures individuelles derrière le nombre d'ouvertures d'un message, de la plus récente à la plus ancienne, chacune marquée human, proxy ou machine. --include-machine ajoute les hits qui n'ont pas été comptés
openemail tracking list-clicks <id>Les clics individuels sur les liens d'un message, du plus récent au plus ancien, chacun avec son url d'origine. --include-machine ajoute les scanners de liens et les répétitions regroupées

tracking list et get-stats couvrent chaque message suivi envoyé par la boîte mail, y compris le courrier rédigé dans l'application web et celui envoyé par les outils MCP ou l'assistant, tandis que emails list contient les enregistrements d'envoi créés par l'API. Un rapport sans enregistrement d'envoi a sendId défini à null.

Exemples

Envoyer depuis un script avec votre propre clé d'idempotence. Le relancer avec la même --idempotency-key affiche le premier e-mail avec replayed: true au lieu d'en envoyer un second.

Envoyer depuis un script
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'

Faites relire une traduction par une personne avant son départ. Envoyez le texte approuvé comme simples --subject et --html, sans --translate, sinon il est traduit une seconde fois. Le html traduit contient déjà votre original en dessous, sauf si vous passez --no-include-original.

Prévisualiser une traduction, puis l'envoyer
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)"

Envoyer un lot depuis un fichier. La commande sort avec le code 0 dès que le lot a été traité, même quand certains éléments ont échoué, lisez donc failed et le status de chaque élément. La relancer avec la même clé rejoue les éléments déjà partis et n'envoie que le reste, tant que le tableau garde son ordre.

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." }]
Envoyer le lot
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

Programmer un e-mail, le déplacer, puis l'annuler. --yes répond à la confirmation que demande cancel, ce qu'un script ne peut pas faire.

Programmer, déplacer et annuler
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

Trouver les envois qui ont échoué et lire ce qui est arrivé à l'un d'eux. Redirigé sans --json, --all affiche un objet JSON par ligne.

Trouver les envois en échec
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'

Lire une semaine d'engagement en jours qui basculent à minuit UTC+2, lister ce que personne n'a ouvert, et compter les clics sur chaque lien d'un message.

Une semaine d'ouvertures et de clics
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 et confirmations

  • Une connexion par navigateur demande des scopes sur la page d'approbation, et openemail login --scopes emails:send,emails:read présélectionne les deux. Une commande dont le scope manque s'arrête avec le code de sortie 4 et insufficient_scope, et nomme le scope.
  • send --attach avec plus de 5 Mo de fichiers les téléverse d'abord dans Fichiers, ce qui nécessite aussi files:write.
  • Aucune de ces commandes ne demande de code de vérification, donc une connexion par navigateur les exécute comme le fait une clé API.
  • emails cancel demande avant d'annuler, et --yes répond pour vous. Sans surveillance et sans --yes, elle s'arrête avec Refusing to run unattended. Pass --yes to confirm. et le code de sortie 2.
  • emails send, send-batch et reschedule ne demandent jamais rien. send affiche un récapitulatif et ne demande que dans un terminal, et --yes saute cela aussi.
  • --dry-run affiche la requête qu'une commande enverrait, n'envoie rien et sort avec le code 0. Sur emails translate, cela ne consomme aucune action d'IA, et sur emails cancel, rien n'est demandé.

Pages de résultats

emails list, emails list-events, tracking list, list-opens et list-clicks lisent une page. --limit fixe sa taille, de 1 à 100 avec 25 par défaut pour les deux listes emails, et de 1 à 200 avec 50 par défaut pour les trois listes tracking. --cursor reprend au curseur qu'une page a affiché.

  • --all lit chaque page et diffuse les éléments : un tableau dans un terminal, et un objet JSON par ligne quand la sortie est redirigée ou avec --ndjson.
  • --max <n> s'arrête après autant d'éléments, et implique --all.
  • --json affiche un seul document { items, hasMore, nextCursor }, --all compris.
  • La pagination se fait par curseur, pas par décalage, donc le courrier envoyé pendant que vous parcourez les pages ne décale ni ne répète jamais une ligne.

Bon à savoir

  • Chaque exécution crée sa propre clé d'idempotence, qui couvre les nouvelles tentatives au sein de cette exécution. Lancer un envoi deux fois envoie deux fois, sauf si les deux exécutions passent la même --idempotency-key. La même clé avec un corps différent est refusée avec idempotency_key_reuse et le code de sortie 7.
  • Seul le courrier queued et scheduled peut être annulé ou déplacé. Un envoi immédiat sans fenêtre d'annulation part au cours de la requête, donc quand vous avez son identifiant, il est en général trop tard, et l'appel se termine avec email_not_cancellable et le code de sortie 6.
  • Un e-mail annulé reste annulé. Reprogrammer ne change que l'heure, comptée pour une durée à partir de la réception de la requête par le serveur : pour changer le texte, annulez et envoyez à nouveau.
  • Une traduction impossible à produire fait refuser tout l'envoi, et rien ne part sans traduction. Un lot traduit contient au plus 10 messages portant translate.
  • Un quota d'envoi épuisé arrête un envoi avec send_quota_exceeded jusqu'au premier du mois, et un quota d'IA épuisé arrête une traduction avec ai_quota_exceeded jusqu'à minuit UTC, tous deux avec le code de sortie 8.
  • Le courrier envoyé avec une clé oe_test_ n'est jamais livré. Il indique sent, avec transport défini à test, et n'est jamais suivi.
  • emails get-tracking et tracking get répondent 404, code de sortie 5, pour un message sans pixel ni lien réécrit, car non suivi n'est pas la même chose que non ouvert. Le suivi respecte le réglage avec lequel le message a été envoyé, donc l'activer plus tard n'atteint pas le courrier antérieur.
  • Chaque chiffre est un minimum. Un lecteur dont le client mail bloque les images ne compte jamais comme une ouverture, et un clic prouve davantage la lecture qu'une ouverture.
  • list-opens et list-clicks répondent 404 pour un identifiant msg_ sans rien de suivi, mais prennent un identifiant tmsg_ tel quel, donc un identifiant inconnu revient sous forme de liste vide.
  • Une clé limitée à certaines adresses ne voit que le courrier envoyé depuis ces adresses, et une clé qui couvre tout un domaine couvre chaque adresse de ce domaine.

Chaque option

Cette page nomme les options qui comptent le plus. openemail <command> --help liste chaque argument et option d'une commande, avec son type, le scope nécessaire, sa méthode et son chemin, ce qu'elle renvoie et les notes de la référence de l'API. Ajoutez --json pour obtenir la même aide sous forme d'un seul document JSON.

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

Votre boîte de réception,
à vos conditions.

L’infrastructure e-mail pour les entreprises, l’IA, les agents et le courrier personnel. Conçue pour l’échelle, la confidentialité et le contrôle. Tout ce que l’e-mail aurait dû avoir dès le premier jour.

OpenEmail

L’infrastructure e-mail pour les entreprises, l’IA, les agents et le courrier personnel. Conçue pour l’échelle, la confidentialité et le contrôle. Tout ce que l’e-mail aurait dû avoir dès le premier jour.

© 2026 OpenEmail. Tous droits réservés.