Aller à la documentation
CLI

Contacts, audiences et diffusions

Chaque commande pour le carnet d'adresses, les audiences, les diffusions et la liste de suppression, avec des exemples détaillés.

Comment elles s'articulent

Quatre espaces de noms couvrent les personnes à qui vous écrivez. Les contacts sont le carnet d'adresses de l'espace de travail, les audiences sont des listes nommées de contacts, une diffusion envoie un message à tous les membres de certaines audiences, et la liste de suppression contient les adresses auxquelles l'espace de travail n'enverra pas. Chaque commande appelle une méthode du SDK, les pages du SDK décrivent donc les mêmes appels plus en détail.

  • Un contact n'a pas d'identifiant. Son adresse est la clé que prend chaque commande contacts, sans espaces autour et en minuscules, donc [email protected] et [email protected] sont un seul contact. Une audience a un identifiant aud_, une diffusion un identifiant brd_, et une suppression l'identifiant qu'affiche suppressions list.
  • Chaque contact fait partie de l'audience par défaut tant qu'il existe. Cette audience ne peut être ni supprimée, ni vidée, ni réduite, et builtin y vaut default.
  • Le carnet d'adresses appartient à l'espace de travail, donc chaque membre et chaque clé lisent et écrivent le même.
  • Chaque espace de noms répond aussi à son singulier, comme dans openemail contact get, et les alias habituels fonctionnent : ls, show, new, edit et rm. Dans suppressions, dont les verbes sont add et remove, new mène à add et rm à remove.

openemail <namespace> <verb> --help montre chaque option avec son type, les scopes, le point de terminaison et ce que renvoie la commande. Ajoutez --json pour obtenir la même page sous forme de données.

Contacts

Le carnet d'adresses de l'espace de travail : les personnes à qui un membre a écrit depuis le compositeur de l'application, plus toute personne enregistrée à la main. Le courrier entrant n'ajoute personne, pas plus qu'un envoi via l'API ou la CLI.

CommandeCe qu'il fait
openemail contacts listUne page des contacts enregistrés, du plus récemment contacté au plus ancien. --source garde les contacts manual ou auto, et --q cherche dans les noms et les adresses
openemail contacts get <email>Un contact, avec chaque audience dont il fait partie
openemail contacts create --email <value>Enregistrer un nouveau contact, avec --name, --notes et --audience-ids. Une adresse déjà dans le carnet est refusée avec 409 contact_exists
openemail contacts update <email>Modifier --name ou --notes, null en effaçant un. L'adresse elle-même ne peut pas changer
openemail contacts delete <email>Supprimer le contact avec ses notes, sa photo et ses appartenances, et masquer l'adresse pour que le compositeur ne l'enregistre plus
openemail contacts set-audiences <email> --audience-ids <a,b>Faire des audiences du contact exactement cette liste. L'audience par défaut est toujours conservée
openemail contacts list-peopleTout le monde sur la page Contacts : les contacts enregistrés et, avec threads:read, chaque adresse vue dans le courrier, avec le nombre de fils. --sort, --q, --email et --blocked filtrent la liste
openemail contacts save <email>Enregistrer une adresse, garder une adresse relevée lors d'un envoi, ou en faire revenir une supprimée. Jamais d'erreur, quel que soit l'état de l'adresse
openemail contacts delete-many <emails...>Supprimer et masquer de 1 à 200 adresses en un appel
openemail contacts set-photo <email> <data>Téléverser la photo depuis un fichier, ou depuis stdin avec - : PNG, JPEG, WebP ou GIF jusqu'à 5 Mo
openemail contacts remove-photo <email>Retirer la photo et supprimer l'image stockée
openemail contacts block <email>Mettre l'adresse sur la liste de blocage de l'espace de travail, pour que le courrier qui en vient soit refusé. Une étiquette plus est retirée
openemail contacts unblock <email>Retirer chaque règle de la liste de blocage qui bloque l'adresse, y compris une règle sur tout le domaine
openemail contacts list-threads <email>Les fils que l'adresse a écrits ou dans lesquels on lui a écrit, dans tous les dossiers. --q cherche à l'intérieur
openemail contacts activity <email>Le courrier reçu de l'adresse et envoyé à celle-ci sur une période, 90 jours sauf si --minutes indique autre chose, avec les fils en attente de réponse et le temps de réponse médian dans chaque sens

Audiences

Des listes nommées de contacts, jusqu'à 100 par espace de travail. Une adresse doit être un contact avant d'en rejoindre une, sauf via import-contacts, qui enregistre les nouvelles adresses au passage.

CommandeCe qu'il fait
openemail audiences listUne page des audiences, l'audience par défaut en premier et les autres de la plus récente à la plus ancienne, chacune avec son contactCount
openemail audiences growthLa croissance des audiences sur une période, 30 jours sauf si --days ou --minutes indique autre chose : adhésions et désabonnements par tranche, et totaux
openemail audiences get <id>Une audience, avec un contactCount à jour
openemail audiences create --name <value>Créer une audience vide, avec une --description facultative. Les noms ne sont pas uniques
openemail audiences update <id>Modifier --name ou --description. Les appartenances ne sont pas touchées
openemail audiences delete <id>Supprimer l'audience et garder ses contacts. L'audience par défaut ne peut pas être supprimée
openemail audiences empty <id>Retirer chaque contact et garder l'audience, avec son identifiant, son nom et sa description
openemail audiences list-contacts <id>Une page des contacts de l'audience, avec la date d'adhésion de chacun et s'il s'est désabonné. --sort, --q, --source et --statuses la filtrent
openemail audiences add-contact <id> --email <value>Mettre un contact existant dans l'audience. Ajouter quelqu'un qui y est déjà ne change rien
openemail audiences remove-contact <id> <email>Retirer un contact. Un contact qui n'est pas dans l'audience donne un 404
openemail audiences add-contacts <id> --emails <a,b>Ajouter jusqu'à 200 contacts existants, et signaler dans missing les adresses qui ne sont pas des contacts
openemail audiences remove-contacts <id> --emails <a,b>Retirer jusqu'à 200 contacts, et signaler ceux qui n'y étaient pas
openemail audiences import-contacts <id> --contacts <json|@file|->Importer jusqu'à 500 lignes { email, name }, en enregistrant les adresses qui ne sont pas encore des contacts

Diffusions

Un message à tous les membres de jusqu'à 10 audiences, envoyé sous forme d'une copie distincte pour chaque personne, avec les champs de fusion remplis et un lien de désabonnement. Chaque copie est un e-mail ordinaire avec son propre identifiant msg_, ses événements et ses webhooks.

CommandeCe qu'il fait
openemail broadcasts preview --audience-ids <a,b>Compter qui une diffusion à ces audiences atteindrait, et qui elle ignorerait comme désabonné ou supprimé. N'envoie rien
openemail broadcasts send --audience-ids <a,b> --from <value>Envoyer avec --subject et --html ou --text, ou un --template enregistré, maintenant ou à --scheduled-at
openemail broadcasts listUne page de diffusions, de la plus récente à la plus ancienne, avec des chiffres en direct. --audience-id garde celles envoyées à cette audience
openemail broadcasts get <id>Une diffusion, avec son statut et ses chiffres en direct : la commande à interroger pendant l'envoi
openemail broadcasts stats <id>Les totaux de livrés, rebonds, ouverts, cliqués et désabonnés, et une série par tranche --grain, d'une heure sauf indication contraire
openemail broadcasts list-recipients <id>À qui chaque copie est allée et ce qu'il en est advenu. --filter garde un groupe, comme bounced ou not_opened
openemail broadcasts get-recipient <id> <email-id>La copie d'une personne, avec l'objet, le HTML et le texte exactement tels qu'elle les a reçus
openemail broadcasts cancel <id>Arrêter une diffusion programmée, en file d'attente ou encore en cours d'envoi. Les copies déjà parties ne peuvent pas être rappelées

Suppressions

Les adresses auxquelles cet espace de travail n'enverra pas : les rebonds définitifs et les plaintes, enregistrés au moment où ils surviennent, et toute adresse ajoutée à la main. Un envoi à l'une d'elles est refusé pour ce destinataire avant que rien ne parte.

CommandeCe qu'il fait
openemail suppressions listUne page de la liste, de la plus récente à la plus ancienne. --reason garde bounce, complaint ou manual, et --q recherche
openemail suppressions get <id>Une ligne : l'adresse, le motif, le détail que portait le rebond ou la plainte, et si elle peut être retirée
openemail suppressions add --email <value>Cesser d'envoyer à une adresse. Ajouter une adresse déjà présente renvoie la ligne qu'elle occupe
openemail suppressions remove <id>Autoriser à nouveau le courrier vers l'adresse. Un rebond définitif ne peut pas être retiré

La liste de suppression et la liste de blocage sont deux listes différentes. suppressions add arrête le courrier sortant vers une adresse, et contacts block refuse le courrier entrant qui en vient.

Scopes

La plupart des commandes ont besoin du scope de lecture ou d'écriture de leur espace de noms. Quelques-unes en demandent un autre, parce qu'elles lisent ou modifient autre chose :

ScopeCommandes
contacts:readcontacts list, get et list-people
contacts:writecontacts create, update, delete, save, delete-many, set-photo et remove-photo, et audiences import-contacts en plus de audiences:write
audiences:readaudiences list, growth, get et list-contacts, ainsi que broadcasts preview, pour qu'une clé qui ne peut pas envoyer puisse quand même afficher le décompte
audiences:writeToutes les autres commandes audiences, et contacts set-audiences. contacts create --audience-ids en a besoin en plus de contacts:write
threads:readcontacts list-threads et activity, ainsi que les adresses vues dans le courrier dans list-people
settings:readsuppressions list et get
settings:writesuppressions add et remove, ainsi que contacts block et unblock
emails:readbroadcasts list, get, stats, list-recipients et get-recipient
emails:sendbroadcasts send, qui a aussi besoin de audiences:read, et broadcasts cancel
  • Une clé limitée à certaines adresses ou certains domaines lit et écrit le même carnet d'adresses que toute autre clé. Elle ne voit que les diffusions envoyées depuis une adresse ou un domaine qu'elle couvre, ne reçoit que les contacts enregistrés de list-people, et se voit refuser avec 422 capability_unsupported par contacts list-threads, activity, block et unblock, ainsi que par suppressions add et remove.
  • Une connexion par navigateur d'un membre qui n'atteint que certaines adresses est refusée avec 422 capability_unsupported sur chaque commande contacts, audiences et broadcasts. suppressions add refuse une connexion par navigateur de quiconque n'est pas le propriétaire de l'espace de travail.

Exemples détaillés

Construire une audience à partir d'un fichier, puis compter qui une diffusion à cette audience atteindrait. import-contacts enregistre les adresses qui ne sont pas encore des contacts, et le relancer ne crée ni n'ajoute rien en double.

contacts.json
[  { "email": "[email protected]", "name": "Ada Lovelace" },  { "email": "[email protected]", "name": "Grace Hopper" },  { "email": "[email protected]" }]
Construire l'audience et la compter
AUDIENCE=$(openemail audiences create --name 'Product updates' --json | jq -r .id)openemail audiences import-contacts "$AUDIENCE" --contacts @contacts.jsonopenemail broadcasts preview --audience-ids "$AUDIENCE"

Vérifier une diffusion avec --dry-run, qui affiche la requête et n'envoie rien, puis l'envoyer. La diffusion est créée tout de suite et envoyée en arrière-plan, interrogez donc get pour la suivre. Ce corps ne place pas {{unsubscribeUrl}}, donc chaque copie reçoit un pied de page de désabonnement d'une ligne.

broadcast.json
{  "audienceIds": ["aud_4c1b8e2a7d9f05c36b4e8a71"],  "from": "Acme <[email protected]>",  "subject": "{{firstName|Hello}}, the September release is out",  "html": "<p>Hi {{firstName|there}},</p><p>Here is what changed this month.</p>",  "scheduledAt": "2026-10-01T09:00:00Z"}
Vérifier la diffusion, puis l'envoyer
openemail broadcasts send --data @broadcast.json --dry-runBROADCAST=$(openemail broadcasts send --data @broadcast.json --yes --json | jq -r .id)openemail broadcasts get "$BROADCAST"openemail broadcasts stats "$BROADCAST" --grain day

Voir qui une diffusion n'a pas atteint. --ndjson affiche un destinataire par ligne, et --all --json un document avec toutes les pages.

Qui elle n'a pas atteint
openemail broadcasts list-recipients brd_5a8c1e3f7b2d94a06c8e1f3b --filter bounced --ndjson | jq -r .emailopenemail broadcasts list-recipients brd_5a8c1e3f7b2d94a06c8e1f3b --filter not_opened --all --json | jq ".items | length"openemail suppressions list --reason bounce --all --max 50

Copier les membres abonnés d'une audience dans une autre. jq transforme le flux en corps que prend add-contacts, et --data - le lit depuis stdin. --max 200 le limite aux 200 adresses qu'accepte un appel.

Copier les membres abonnés
openemail audiences list-contacts aud_9f2c4b7e1a0d63d84c5f2e7b --statuses subscribed --max 200 --ndjson \  | jq -s '{ emails: map(.email) }' \  | openemail audiences add-contacts aud_1c4e7a9b2d0f36e85a7c1b4d --data -

Supprimer chaque contact que le compositeur a relevé sur un domaine. delete-many prend jusqu'à 200 adresses par appel, donc xargs -n 200 découpe une liste plus longue. Vérifiez d'abord les lots avec --dry-run, car il n'y a pas d'annulation possible.

Supprimer par domaine
openemail contacts list --source auto --all --ndjson \  | jq -r 'select(.email | endswith("@old-vendor.example")) | .email' > leaving.txtxargs -n 200 openemail contacts delete-many --dry-run < leaving.txtxargs -n 200 openemail contacts delete-many --yes < leaving.txt

Cesser d'envoyer à une adresse, en autoriser une à nouveau et bloquer un expéditeur. removable indique quelles lignes suppressions remove acceptera.

Supprimer, autoriser et bloquer
openemail suppressions add --email [email protected]openemail suppressions list --q [email protected] --json | jq -r '.items[] | select(.removable) | .id'openemail suppressions remove 7b1e2c3d-4f5a-4b6c-8d7e-9f0a1b2c3d4e --yesopenemail contacts block [email protected]

Confirmations et codes de vérification

Ces commandes demandent confirmation dans un terminal avant de s'exécuter :

Espace de nomsDemande confirmation
contactsdelete, delete-many, remove-photo et unblock
audiencesdelete, empty, remove-contact et remove-contacts
broadcastssend et cancel
suppressionsremove
  • --yes confirme pour vous. Sans surveillance, avec --json ou --no-input, en CI ou sans terminal, une commande qui demanderait confirmation s'arrête avec Refusing to run unattended. Pass --yes to confirm. et le code de sortie 2.
  • --dry-run affiche la requête que la commande enverrait et sort avec le code 0, sans rien demander ni rien changer.
  • Avec une connexion par navigateur, audiences delete demande d'abord un code de vérification, comme le fait l'application web. --yes ne le saute jamais, et sans surveillance la commande s'arrête avec le code de sortie 4. Lancez openemail verify au préalable, ou utilisez une clé API, à laquelle on ne demande jamais de code.
  • audiences empty ne demande jamais de code de vérification, vérifiez donc l'identifiant avant de passer --yes.

Pagination

Chaque commande qui liste lit une page. Quand il en reste d'autres, passez le curseur affiché à --cursor, avec les mêmes filtres, ou lisez-les toutes :

  • --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.
  • Un curseur mal formé ou périmé donne un 400 invalid_cursor. Recommencez sans curseur.
CommandeTaille de page
openemail contacts listDe 1 à 200, 50 sauf si --limit indique autre chose
openemail contacts list-peopleDe 1 à 100, 25 sauf si --limit indique autre chose
openemail contacts list-threadsDe 1 à 100, 25 sauf si --limit indique autre chose
openemail audiences listDe 1 à 100, 25 sauf si --limit indique autre chose
openemail audiences list-contactsDe 1 à 200, 50 sauf si --limit indique autre chose
openemail broadcasts listDe 1 à 100, 25 sauf si --limit indique autre chose
openemail broadcasts list-recipientsDe 1 à 200, 50 sauf si --limit indique autre chose
openemail suppressions listDe 1 à 100, 25 sauf si --limit indique autre chose

Bon à savoir

  • contacts create refuse une adresse déjà dans le carnet avec 409 contact_exists, pour qu'une nouvelle tentative n'écrase jamais un nom que quelqu'un a modifié. contacts save ne refuse jamais : elle enregistre, garde ou fait revenir l'adresse, quel que soit son état.
  • contacts delete accepte aussi une adresse qui n'a jamais été vue que dans le courrier, ce qui retire cette personne de list-people. Le courrier reste. Il n'y a pas d'annulation possible : enregistrer à nouveau l'adresse crée un contact sans nom, sans notes et sans autre audience que celle par défaut.
  • L'adresse est l'identité d'un contact, donc contacts update ne peut pas la changer. Déplacer un contact, c'est un delete suivi d'un create.
  • contacts set-photo lit l'image depuis un fichier, ou depuis stdin avec -. Passez --content-type, comme image/jpeg : sans cela, l'image peut partir en application/octet-stream, que le serveur refuse avec 422 invalid_image.
  • broadcasts send --scheduled-at accepte une heure ISO 8601 comme 2026-10-01T09:00:00Z, ou une durée ISO 8601 comme PT2H ou P1D, jusqu'à 365 jours dans le futur. Les délais courts qu'accepte send --at, comme 2h, sont refusés ici.
  • Les champs de fusion fonctionnent dans --subject, --html et --text : {{firstName}}, {{lastName}}, {{name}}, {{email}} et {{unsubscribeUrl}}, chacun avec une valeur de repli après une barre verticale, comme dans {{firstName|there}}. Un corps qui ne place pas {{unsubscribeUrl}} reçoit un pied de page de désabonnement d'une ligne. Un modèle est envoyé tel quel, mettez donc le lien dans le modèle.
  • Une diffusion est vérifiée par rapport aux envois mensuels du forfait avant que quoi que ce soit ne soit écrit, et chaque copie compte comme un envoi. Une diffusion que le quota ne peut pas couvrir est refusée avec 429 send_quota_exceeded, et rien ne reste derrière.
  • Passez votre propre --idempotency-key à broadcasts send quand un script risque de relancer l'étape. La même clé répond avec la diffusion qu'elle a créée au lieu d'en envoyer une nouvelle.
  • Un contact qui se désabonne d'une diffusion reste dans l'audience avec unsubscribedAt défini, et les diffusions suivantes vers cette audience l'ignorent. audiences list-contacts --statuses unsubscribed les liste.
  • Un rebond définitif reste sur la liste de suppression. suppressions remove le refuse avec 409 suppression_not_removable, et removable l'indique à l'avance sur chaque ligne.

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.