Skip to content

Send one message to a list of people

Keep contacts in an audience, send a broadcast to all of them, and handle the unsubscribe that follows.

A transactional message goes to an address you already have in hand. Marketing mail works the other way round: you keep a list of people and send one message to all of them. That list is an audience, the people on it are contacts, and the message is a broadcast.

Everything here belongs to one product. For the transactional side — one message to one address, triggered by something that happened — see How system email works.

Put people in an audience

An audience is a named bucket: a name of 1 to 200 characters, and nothing else. You create them, rename them, list them and delete them.

MCP. mail_audience_create, mail_audience_list, mail_audience_update, mail_audience_delete.

A contact is a person you may send marketing mail to:

FieldWhat it holds
emailThe address, stored trimmed and lower-cased
propertiesYour own key/value pairs — first_name, plan, anything you like
unsubscribedWhether this person has opted out
audienceIdThe audience the contact belongs to

properties is free-form: keys are yours to choose and values are ordinary JSON. Two of them mean something — first_name and last_name are offered to templates — and the rest are simply carried along.

MCP. mail_contact_create, mail_contact_list, mail_contact_get, mail_contact_update, mail_contact_delete.

Two rules worth knowing before you design your lists:

  • Updating a contact replaces the whole properties object rather than merging into it, so send back the fields you want to keep. The same call sets or clears unsubscribed.
  • A contact belongs to exactly one audience. An address may appear in several audiences, but only once in each, so the same person can be on both “product updates” and “beta testers” as two separate contacts, each with its own properties and its own opt-out state. There is no way to move a contact between audiences: create it in the other audience and delete the original.

Deleting an audience deletes the contacts in it.

Contacts are listed one audience at a time, between 1 and 100 at a time (50 by default) with a cursor for the next page, and can be narrowed to only the unsubscribed or only the subscribed.

Send a broadcast

A broadcast is one message to one audience. It is created as a draft and sends nothing until you queue it.

  1. Create the draft. It needs a name, the audience to send to, and a from address at one of your verified domains — the same rule as any other send, see Verify a sending domain. It may also carry reply-to addresses and custom headers.
  2. Give it content. Choose one of two forms and do not mix them: inline — a subject, plus HTML or plain text (or both); or a template — the id of a published template with the variables to render it with, see Write a template.
  3. Queue it. This is the point of no return.

MCP. mail_broadcast_create, mail_broadcast_update, mail_broadcast_queue, mail_broadcast_get, mail_broadcast_list.

While it is a draft, a broadcast can be edited freely and deleted. Once it leaves that state neither is possible: editing or deleting a queued, sent, failed or cancelled broadcast is refused.

What queuing does

The broadcast moves to queued and is then fanned out: the audience is walked and one ordinary email is created per eligible contact. Two kinds of contact are skipped:

  • Anyone whose unsubscribed flag is set is not even considered.
  • Anyone whose address is on the product’s suppression list is recorded as skipped and no message is created — see Keep your mail deliverable.

Each message that is created goes through the normal send path from there, with its own status and its own events, and each carries a per-recipient unsubscribe header. Because a broadcast is many messages they do not all leave at once: the audience is worked through in pages, and the broadcast becomes sent when the last of them has been handed on.

When the content comes from a template, each contact’s message is rendered with the broadcast’s own variables plus four filled in for you:

VariableValue
FIRST_NAMEThe contact’s first_name property, or empty
LAST_NAMEThe contact’s last_name property, or empty
EMAILThe contact’s address
UNSUBSCRIBE_URLThat contact’s unsubscribe link

UNSUBSCRIBE_URL is what lets you put a visible “unsubscribe” link in the body of the message itself, next to the one the mail client offers.

Cancelling it

A broadcast can be cancelled while it is a draft or while it is queued. Cancelling a draft simply stops it ever going out. Cancelling one that is already being fanned out stops it between pages: messages already created are on their way and are not recalled, but no further contact is reached. Anything already sent, failed or cancelled cannot be cancelled.

If the fan-out itself cannot complete, the broadcast ends as failed and keeps the reason it failed with.

MCP. mail_broadcast_cancel, mail_broadcast_delete.

Read what happened

Each broadcast reports on itself. MCP: mail_broadcast_stats.

FieldMeaning
recipientsContacts a message was created for
suppressedContacts skipped because the address was suppressed
failedContacts whose message could not be created
deliveredMessages the receiving servers accepted
bouncedMessages that were rejected
opened, clickedOpens and link clicks, when tracking is on for the sending domain

The first three add up to the contacts the fan-out considered. The rest arrive afterwards, as the outcomes come back, so they keep rising for a while after the broadcast is sent. For an event per message rather than a total, see Receive mail webhooks.

Handle unsubscribes

Every message created by a broadcast carries the two headers that let a mail client offer a one-click unsubscribe of its own: List-Unsubscribe, holding a link unique to that contact, and List-Unsubscribe-Post, which tells the client the link can be triggered directly. The link is signed, so it cannot be forged or edited to point at someone else, and it does not expire.

Opening the link in a browser shows a short confirmation page with a button and changes nothing by itself — mailbox scanners follow links in mail, and a link that unsubscribed people merely for being visited would opt out people who never asked to leave. The opt-out happens only when the button is pressed, or when a mail client triggers the link directly. Using the same link twice does nothing the second time.

When it does happen, two things follow at once:

  1. The contact is marked unsubscribed, so no later broadcast to that audience includes them.
  2. Their address is added to the product’s suppression list with the reason unsubscribe, so no later message of any kind reaches it.

That second step reaches your transactional mail too. An opt-out from a marketing message stops your receipts and password resets to the same address. If a recipient asks to come back, remove the address from the suppression list and clear the contact’s unsubscribed flag — both sides have to be undone.

MCP. mail_suppression_list, mail_suppression_remove.

Next steps

Was this page helpful?
Esc

Start typing to search the docs.

navigateselect