Diffusions
`broadcasts.preview`, `send`, `list`, `list_all`, `iterate`, `get`, `list_recipients`, `list_all_recipients`, `iterate_recipients`, `get_recipient`, `stats`, `analytics` et `cancel`.
Toutes les méthodes
import time from openemail import openemailfrom openemail.types import BroadcastCreate draft: BroadcastCreate = { '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>', 'text': 'Hi {{firstName|there}}, here is what changed this month. Unsubscribe: {{unsubscribeUrl}}', 'tags': {'campaign': 'release-2026-09'},} reach = openemail.broadcasts.preview(draft)print(reach['recipients'], reach['unsubscribed'], reach['suppressed']) broadcast = openemail.broadcasts.send(draft) latest = openemail.broadcasts.get(broadcast['id'])while latest['status'] in ('scheduled', 'queued', 'sending'): time.sleep(5) latest = openemail.broadcasts.get(broadcast['id']) for copy in openemail.broadcasts.iterate_recipients(broadcast['id']): print(copy['email'], copy['status'], copy['opens'], copy['clicks']) bounced = openemail.broadcasts.list_recipients(broadcast['id'], filter='bounced')if bounced['items']: content = openemail.broadcasts.get_recipient(broadcast['id'], bounced['items'][0]['emailId']) print(content['subject'], content['bouncedAt']) stats = openemail.broadcasts.stats(broadcast['id'], grain='day')print(stats['totals']['opened'], stats['totals']['clicked'], stats['totals']['unsubscribed']) lately = openemail.broadcasts.stats(broadcast['id'], days=1)print(lately['window']['opened'] if lately['window'] else None) month = openemail.broadcasts.analytics(days=30)for row in month['broadcasts']: print(row['subject'], row['sent'], row['opened']) later = openemail.broadcasts.send({**draft, 'scheduledAt': 'P1D'})openemail.broadcasts.cancel(later['id']) history = openemail.broadcasts.list(audience_id=draft['audienceIds'][0])print(latest['status'], latest['counts']['sent'], len(history['items']))Une diffusion envoie un message à tous les membres d'une ou plusieurs audiences, sous forme de copie distincte pour chaque personne. Chaque copie a exactement un destinataire et ni cc ni bcc, si bien que personne ne voit à qui d'autre elle est partie, et chaque copie est un e-mail ordinaire avec son propre identifiant msg_, ses événements, son suivi et ses webhooks. list_recipients les liste avec ce qu'il est advenu de chacune. Les copies ne sont pas classées dans le dossier Envoyés, car la diffusion en fait foi.
send renvoie aussitôt la diffusion en queued, ou en scheduled si vous passez scheduledAt, et l'envoi se poursuit en arrière-plan. send exige emails:send et audiences:read, preview exige audiences:read, list, list_all, iterate, get, list_recipients, list_all_recipients, iterate_recipients, get_recipient, stats et analytics exigent emails:read, et cancel exige emails:send.
Chaque send porte une Idempotency-Key, la vôtre via idempotency_key= ou une que le SDK crée, si bien qu'une nouvelle tentative après une panne réseau répond avec la diffusion créée par la première tentative au lieu d'envoyer deux fois. preview, get, cancel et toutes les lectures peuvent être répétés sans risque et sont réessayés.
Champs de fusion
subject, html et text sont remplis pour chaque personne à partir de son contact. {{firstName}} est le premier mot du nom du contact, {{lastName}} le reste, {{name}} le nom complet, {{email}} l'adresse à laquelle part la copie et {{unsubscribeUrl}} le lien qui la désabonne.
Chaque champ accepte une valeur de repli après une barre, utilisée quand le contact n'a pas de valeur pour lui : {{firstName|there}} devient donc "there" pour un contact enregistré sans nom. Les valeurs sont échappées dans html, et tout autre {{…}} est laissé exactement tel qu'il est écrit.
Passez template à la place de html et text pour envoyer un modèle enregistré. Les cinq mêmes valeurs lui parviennent comme props, mais seulement les props que le modèle déclare : un modèle qui déclare firstName le reçoit, et un modèle qui ne le déclare pas n'est jamais refusé pour autant. Tout ce qui est dans template.props va à l'identique dans chaque copie.
Désabonnement
Chaque copie porte les en-têtes de désabonnement en un clic qui permettent à un client de messagerie d'afficher son propre bouton de désabonnement, ce que les grands fournisseurs de boîtes exigent du courrier en masse. Un corps html ou text qui ne place pas {{unsubscribeUrl}} lui-même reçoit un pied de page d'une ligne avec le lien. Un modèle est envoyé exactement tel quel : mettez donc {{unsubscribeUrl}} dans le modèle.
Le désabonnement marque la personne désabonnée dans chaque audience à laquelle cette diffusion est partie, et AudienceContactResource.unsubscribedAt l'indique sur audiences.list_contacts. Elle reste dans l'audience et dans le carnet d'adresses, ses autres audiences ne sont pas touchées, et le courrier qui lui est envoyé un message à la fois part toujours. La retirer de l'audience puis l'y rajouter la réabonne.
Qui est ignoré
Une diffusion atteint chaque contact d'au moins une des audienceIds, une fois quel que soit le nombre d'audiences qui le contiennent. Elle ignore le contact qui s'est désabonné de chacune de ces audiences dont il fait partie, et l'adresse figurant sur la liste de suppression après un rebond ou une plainte, ou parce que quelqu'un l'y a ajoutée. Un contact ajouté à l'une des audiences après send, mais avant que l'envoi ne l'atteigne, est inclus.
preview renvoie les mêmes chiffres sans envoyer : recipients, unsubscribed et suppressed. Un send qui n'atteindrait personne lève 422 no_recipients.
L'envoi entier est confronté aux envois mensuels de la formule avant toute écriture, si bien qu'une diffusion que le quota ne peut pas couvrir lève 429 send_quota_exceeded et ne laisse rien derrière elle. Chaque copie compte pour un envoi.
Statut et avancement
get lit counts en direct depuis les copies : interrogez-le pendant qu'une diffusion part. status passe de scheduled ou queued à sending et se fixe sur sent une fois que chaque copie confiée est partie ou a échoué. Il reste sending tant que des copies attendent encore, même après que completedAt indique que la dernière personne a été atteinte. failed signifie que la diffusion entière s'est arrêtée, et lastError dit pourquoi : l'adresse from ne peut plus servir à envoyer, le modèle ne se résout plus, la formule s'est épuisée en route, l'envoi lui-même a échoué à répétition, ou pas une seule copie n'a pu être écrite.
cancel arrête une diffusion scheduled, queued ou sending. Personne d'autre n'est ajouté et chaque copie encore en attente est annulée, tandis que les copies parties ne peuvent pas être rappelées. Une fois toutes les copies parties, cancel lève 409 broadcast_not_cancellable, et annuler une diffusion déjà annulée la renvoie telle qu'elle est.
Qui elle a atteint
list_recipients renvoie une page des personnes auxquelles une diffusion est partie, une ligne par copie, triées par adresse, sous la forme d'un dictionnaire avec items, hasMore et nextCursor. list_all_recipients parcourt toutes les pages dans une seule liste et iterate_recipients fournit une copie à la fois, en ne récupérant la page suivante que lorsque la boucle la demande. limit va de 1 à 200 et vaut 50 par défaut, et un cursor se renvoie avec les mêmes filter et q.
| filter | Garde |
|---|---|
| pending | Copies encore en file d'attente, programmées ou en cours d'envoi. |
| sent | Copies parties. |
| delivered | Copies acceptées par le serveur destinataire. |
| opened | Copies ouvertes au moins une fois. |
| not_opened | Copies envoyées et jamais ouvertes. |
| clicked | Copies avec au moins un clic suivi. |
| bounced | Copies qui ont rebondi. |
| complained | Copies que la personne a signalées comme spam. |
| failed | Copies échouées ou annulées. |
| unsubscribed | Personnes qui se sont désabonnées après le départ de la diffusion. |
BROADCAST_RECIPIENT_FILTERS nomme chaque filtre, et q cherche dans l'adresse et le nom, sans tenir compte de la casse. Les ouvertures et les clics excluent les proxys d'images et les scanners de liens, et restent à 0 quand la diffusion est partie avec le suivi désactivé.
get_recipient(id, email_id) renvoie une copie : la même ligne, plus subject, html et text exactement tels que cette personne les a reçus, avec les champs de fusion remplis et son propre lien de désabonnement. Le HTML est celui d'avant l'ajout du suivi des ouvertures et des clics. Un email_id qui n'est pas une copie de cette diffusion lève une erreur 404 recipient_not_found, et une diffusion inconnue lève une erreur 404 broadcast_not_found.
stats renvoie les totaux et une série. totals compte les copies sent, delivered, bounced, complained et failed, avec pending pour celles encore en attente, et les personnes qui ont opened, clicked et unsubscribed, avec opens et clicks comme nombres d'événements. series est clairsemée et commence par le plus ancien, un intervalle par grain (minute, hour ou day, hour par défaut) dans lequel quelque chose s'est produit, découpé selon offset_minutes à l'est d'UTC. Elle compte chaque personne une seule fois, au premier moment où cela lui est arrivé, si bien que son total correspond aux totaux.
Une clé limitée à certaines adresses ou certains domaines n'atteint que les diffusions envoyées depuis une adresse ou un domaine qu'elle détient. list, list_all et iterate laissent les autres de côté, et get, les méthodes des destinataires, stats et cancel lèvent 404 broadcast_not_found pour elles.
Réponse : BroadcastResource
get et cancel renvoient chacun un de ces objets, et send renvoie un SentBroadcastResource, les mêmes champs plus replayed, qui vaut True quand la réponse est la diffusion qu'un appel antérieur avec la même clé d'idempotence a créée. list en renvoie une page, un dictionnaire avec items, hasMore et nextCursor, de la plus récente à la plus ancienne, et list_all et iterate parcourent toutes les pages. preview renvoie un BroadcastPreviewResource avec audienceIds, recipients, unsubscribed et suppressed. list_recipients renvoie une page de lignes BroadcastRecipientResource, get_recipient un BroadcastRecipientContentResource et stats un BroadcastStatsResource.
idstr- La référence durable, `brd_` suivi de 24 caractères hexadécimaux.
statusBroadcastStatus- `scheduled`, `queued`, `sending`, `sent`, `cancelled` ou `failed`. `BROADCAST_STATUSES` nomme chacun.
modeApiKeyMode- `live` ou `test`, selon la clé qui l'a créée. Les copies d'une diffusion de test sont marquées envoyées et ne sont remises à personne.
sourceEmailSource | str- D'où elle a été lancée : `api` pour une clé, `oauth` pour une application connectée, `composer` pour l'application, `mcp` pour un assistant.
audienceIdslist[str]- Les audiences auxquelles elle est partie, chacune une fois.
fromstr- L'adresse depuis laquelle chaque copie est envoyée.
subjectstr- L'objet tel qu'écrit, champs de fusion compris. Vide quand un modèle fournit l'objet.
countsBroadcastCounts- `recipients` est l'estimation prise au `send`. `created` compte les copies écrites, `skipped` les personnes laissées de côté parce que leur adresse était supprimée à ce moment-là, et `failedToQueue` les personnes dont la copie n'a pas pu être écrite. `queued`, `sending`, `sent`, `failed` et `cancelled` comptent les copies selon l'état où chacune se trouve maintenant.
lastErrorstr | None- Pourquoi la diffusion a échoué, ou la copie la plus récente qui n'a pas pu être écrite et pourquoi. `None` tant que rien n'a mal tourné.
scheduledAtstr | None- ISO-8601 UTC, quand l'envoi doit démarrer. `None` pour une diffusion envoyée tout de suite.
startedAtstr | None- ISO-8601 UTC, quand l'envoi a atteint les premières personnes.
completedAtstr | None- ISO-8601 UTC, quand la dernière personne a été atteinte. Des copies peuvent encore attendre de partir après.
cancelledAtstr | None- ISO-8601 UTC, quand `cancel` l'a arrêtée.
createdAtstr- ISO-8601 UTC, quand `send` a été appelé. Fixe l'ordre de la liste.
updatedAtstr- ISO-8601 UTC, mis à jour à mesure que l'envoi avance.
Réponse : BroadcastRecipientResource
Chaque ligne de list_recipients, list_all_recipients et iterate_recipients. BroadcastRecipientContentResource, issu de get_recipient, ajoute subject, html et text.
emailIdstr- L'identifiant `msg_` de la copie de cette personne. `get_recipient` la lit avec son contenu et `emails.get` la lit comme un e-mail envoyé.
contactIdstr | None- Le contact auquel elle est partie, ou `None` quand le contact a été supprimé depuis.
emailstr- L'adresse à laquelle la copie est partie.
namestr | None- Le nom du contact.
statusstr- L'état de la copie : `queued`, `scheduled`, `sending`, `sent`, `failed` ou `cancelled`.
sentAtstr | None- ISO-8601 UTC, moment où la copie est partie.
deliveredAtstr | None- ISO-8601 UTC, moment où le serveur destinataire l'a acceptée, le premier `email.delivered`.
bouncedAtstr | None- ISO-8601 UTC, moment où elle a rebondi, le premier `email.bounced`.
complainedAtstr | None- ISO-8601 UTC, moment où la personne l'a signalée comme spam, le premier `email.complained`.
failurestr | None- Pourquoi la copie a échoué, le cas échéant.
opensint- Ouvertures enregistrées, sans celles des proxys d'images et des scanners. 0 quand le suivi était désactivé.
firstOpenAtstr | None- ISO-8601 UTC, la première ouverture.
clicksint- Clics enregistrés sur les liens suivis, sans les scanners.
firstClickAtstr | None- ISO-8601 UTC, le premier clic.
unsubscribedAtstr | None- ISO-8601 UTC, moment où cette personne s'est désabonnée de l'une des audiences de la diffusion après son départ, par son lien ou autrement.
Référence
broadcasts.preview()Référence complètebroadcasts.send()Référence complètebroadcasts.list()Référence complètebroadcasts.list_all()Référence complètebroadcasts.iterate()Référence complètebroadcasts.get()Référence complètebroadcasts.list_recipients()Référence complètebroadcasts.list_all_recipients()Référence complètebroadcasts.iterate_recipients()Référence complètebroadcasts.get_recipient()Référence complètebroadcasts.stats()Référence complètebroadcasts.analytics()Référence complètebroadcasts.cancel()Référence complète