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 identifiantaud_, une diffusion un identifiantbrd_, et une suppression l'identifiant qu'affichesuppressions 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
builtiny vautdefault. - 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,editetrm. Danssuppressions, dont les verbes sontaddetremove,newmène àaddetrmà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.
| Commande | Ce qu'il fait |
|---|---|
| openemail contacts list | Une 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-people | Tout 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.
| Commande | Ce qu'il fait |
|---|---|
| openemail audiences list | Une 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 growth | La 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.
| Commande | Ce 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 list | Une 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.
| Commande | Ce qu'il fait |
|---|---|
| openemail suppressions list | Une 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 :
| Scope | Commandes |
|---|---|
| contacts:read | contacts list, get et list-people |
| contacts:write | contacts create, update, delete, save, delete-many, set-photo et remove-photo, et audiences import-contacts en plus de audiences:write |
| audiences:read | audiences 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:write | Toutes les autres commandes audiences, et contacts set-audiences. contacts create --audience-ids en a besoin en plus de contacts:write |
| threads:read | contacts list-threads et activity, ainsi que les adresses vues dans le courrier dans list-people |
| settings:read | suppressions list et get |
| settings:write | suppressions add et remove, ainsi que contacts block et unblock |
| emails:read | broadcasts list, get, stats, list-recipients et get-recipient |
| emails:send | broadcasts 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 422capability_unsupportedparcontacts list-threads,activity,blocketunblock, ainsi que parsuppressions addetremove. - Une connexion par navigateur d'un membre qui n'atteint que certaines adresses est refusée avec 422
capability_unsupportedsur chaque commandecontacts,audiencesetbroadcasts.suppressions addrefuse 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.
[ { "email": "[email protected]", "name": "Ada Lovelace" }, { "email": "[email protected]", "name": "Grace Hopper" }, { "email": "[email protected]" }]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.
{ "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"}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 dayVoir qui une diffusion n'a pas atteint. --ndjson affiche un destinataire par ligne, et --all --json un document avec toutes les pages.
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 50Copier 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.
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.
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.txtCesser d'envoyer à une adresse, en autoriser une à nouveau et bloquer un expéditeur. removable indique quelles lignes suppressions remove acceptera.
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 noms | Demande confirmation |
|---|---|
| contacts | delete, delete-many, remove-photo et unblock |
| audiences | delete, empty, remove-contact et remove-contacts |
| broadcasts | send et cancel |
| suppressions | remove |
--yesconfirme pour vous. Sans surveillance, avec--jsonou--no-input, en CI ou sans terminal, une commande qui demanderait confirmation s'arrête avecRefusing to run unattended. Pass --yes to confirm.et le code de sortie2.--dry-runaffiche la requête que la commande enverrait et sort avec le code0, sans rien demander ni rien changer.- Avec une connexion par navigateur,
audiences deletedemande d'abord un code de vérification, comme le fait l'application web.--yesne le saute jamais, et sans surveillance la commande s'arrête avec le code de sortie4. Lancezopenemail verifyau préalable, ou utilisez une clé API, à laquelle on ne demande jamais de code. audiences emptyne 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 :
--alllit 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.--jsonaffiche un seul document{ items, hasMore, nextCursor },--allcompris.- Un curseur mal formé ou périmé donne un 400
invalid_cursor. Recommencez sans curseur.
| Commande | Taille de page |
|---|---|
| openemail contacts list | De 1 à 200, 50 sauf si --limit indique autre chose |
| openemail contacts list-people | De 1 à 100, 25 sauf si --limit indique autre chose |
| openemail contacts list-threads | De 1 à 100, 25 sauf si --limit indique autre chose |
| openemail audiences list | De 1 à 100, 25 sauf si --limit indique autre chose |
| openemail audiences list-contacts | De 1 à 200, 50 sauf si --limit indique autre chose |
| openemail broadcasts list | De 1 à 100, 25 sauf si --limit indique autre chose |
| openemail broadcasts list-recipients | De 1 à 200, 50 sauf si --limit indique autre chose |
| openemail suppressions list | De 1 à 100, 25 sauf si --limit indique autre chose |
Bon à savoir
contacts createrefuse une adresse déjà dans le carnet avec 409contact_exists, pour qu'une nouvelle tentative n'écrase jamais un nom que quelqu'un a modifié.contacts savene refuse jamais : elle enregistre, garde ou fait revenir l'adresse, quel que soit son état.contacts deleteaccepte aussi une adresse qui n'a jamais été vue que dans le courrier, ce qui retire cette personne delist-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 updatene peut pas la changer. Déplacer un contact, c'est undeletesuivi d'uncreate. contacts set-photolit l'image depuis un fichier, ou depuis stdin avec-. Passez--content-type, commeimage/jpeg: sans cela, l'image peut partir enapplication/octet-stream, que le serveur refuse avec 422invalid_image.broadcasts send --scheduled-ataccepte une heure ISO 8601 comme2026-10-01T09:00:00Z, ou une durée ISO 8601 commePT2HouP1D, jusqu'à 365 jours dans le futur. Les délais courts qu'acceptesend --at, comme2h, sont refusés ici.- Les champs de fusion fonctionnent dans
--subject,--htmlet--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 sendquand 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
unsubscribedAtdéfini, et les diffusions suivantes vers cette audience l'ignorent.audiences list-contacts --statuses unsubscribedles liste. - Un rebond définitif reste sur la liste de suppression.
suppressions removele refuse avec 409suppression_not_removable, etremovablel'indique à l'avance sur chaque ligne.