Send one message to a list of people
Create an audience, send a broadcast, check delivery, and manage unsubscribes.
To send the same marketing message to a list of people, add contacts to an audience, then create and queue a broadcast for that audience. Mail attempts to create a separate email for each eligible contact.
You need a verified sending domain for the from address. To personalize the message for each contact, you also need a published template. All audiences, contacts, and broadcasts belong to one product.
Use the MCP tools linked below or the REST API. Audiences, contacts, and broadcasts have no workspace screens. The suppression list is available at Mail → Suppressions.
Check your unsubscribe handling before sending: a broadcast unsubscribe suppresses the address across the product, including receipts and password resets. Handle unsubscribes explains the effect and how to resume sending when a recipient asks to return. For individual messages triggered by a user’s action, see how system email works.
Put people in an audience
- Create an audience with
mail_audience_create. Give it a name of 1–200 characters, such as “Product updates.” An audience stores only its name; contact details belong on its contacts. - Add contacts with
mail_contact_create. Each needs an email address and the audience to join. Add properties if your template needs them. - Check the list with
mail_contact_list. It returns one audience’s contacts, 50 per page by default. You can request 1–100, follow the cursor to the next page, and filter for subscribed or unsubscribed contacts. Confirm the intended recipients are subscribed before you queue a broadcast.
Each contact has these fields:
Field | What it holds |
|---|---|
email | The address, with surrounding whitespace removed and letters lowercased |
properties | Your JSON key/value pairs, such as first_name or plan |
unsubscribed | Whether the contact has opted out |
audienceId | The audience the contact belongs to |
Mail supplies first_name and last_name to templates. Other property names are yours to choose, and their JSON values are stored with the contact.
Use mail_contact_get to read a contact and mail_contact_update to change its properties or unsubscribed flag. An update replaces the whole properties object. Include every property you want to keep. Remove a contact with mail_contact_delete.
A contact belongs to exactly one audience. The same address can appear once in each of several audiences: for example, “Product updates” and “Beta testers” can each have a separate contact with its own properties and opt-out flag. To move a contact, create it in the destination audience and delete the original.
To manage the audience itself, use mail_audience_get, mail_audience_list, or mail_audience_update. Deleting an audience with mail_audience_delete also deletes its contacts.
Send a broadcast
- Prepare the content. Choose either inline content—a subject and HTML, plain text, or both—or a published template with its variables. You cannot mix the two forms. See send from a template.
- Create a draft with
mail_broadcast_create. Supply the content, a name, the audience, and afromaddress on a verified sending domain. You can also supply reply-to addresses and custom headers. Creating the draft sends nothing. - Review the draft. Read it with
mail_broadcast_get. Usemail_broadcast_updateto edit it ormail_broadcast_deleteto remove it. Both actions are available only while its status isdraft. - Queue the broadcast with
mail_broadcast_queue. This starts creating emails for the audience. You can no longer edit or delete the broadcast, and canceling it cannot recall emails already created. - Check progress with
mail_broadcast_get. The status isqueuedwhile Mail processes the audience andsentwhen it has handed on the last message. Usemail_broadcast_listto find other broadcasts. Check delivery separately in the broadcast statistics.
What queuing does
Before queueing, Mail checks the plan allowance once for the eligible audience. A refusal returns HTTP 402 with entitlement_exhausted or entitlement_unavailable, leaves the broadcast in draft, and sends nothing. Read the returned reason and resolve that condition before queueing again. A successful check covers this broadcast’s audience processing; the allowance is not checked again for each contact.
Mail processes the audience in pages and creates one email per eligible contact:
- Contacts with
unsubscribedset are excluded. - Addresses on the product’s suppression list are counted as skipped, and no email is created for them.
Each created email follows the normal send process, with its own status, events, and unsubscribe headers. A broadcast’s sent status means audience processing has finished; delivery outcomes can still arrive afterward.
For template content, Mail combines the broadcast’s variables with these per-contact values:
Variable | Value |
|---|---|
FIRST_NAME | The contact’s first_name property, or empty |
LAST_NAME | The contact’s last_name property, or empty |
EMAIL | The contact’s email address |
UNSUBSCRIBE_URL | The contact’s unsubscribe link |
Use UNSUBSCRIBE_URL for a visible unsubscribe link in the email body. The email also carries headers that let the mail client offer its own unsubscribe action.
Cancel one
Call mail_broadcast_cancel while the broadcast is draft or queued. Canceling a draft prevents it from sending. Canceling a queued broadcast stops audience processing between pages; emails already created continue through the send process and cannot be recalled.
You cannot cancel a broadcast that is already sent, failed, or canceled. If audience processing fails, the broadcast has status failed and retains the reason for the failure.
Read what happened
Call mail_broadcast_stats for the broadcast’s counts:
Field | Meaning |
|---|---|
recipients | Contacts whose message was accepted, created, and queued |
suppressed | Contacts skipped because their address was suppressed |
failed | Contacts whose message could not be created or accepted into the queue; excludes later delivery failures |
delivered | Messages accepted by receiving servers |
bounced | Messages rejected by receiving servers |
opened, clicked | Messages opened at least once; messages with at least one tracked click, when enabled for the sending domain |
recipients, suppressed, and failed are separate sets. Their sum is the number of contacts processed by Mail. This can differ from recipientCount, which counts the eligible audience when you queue: contacts can change between queueing and processing. Delivery, bounce, open, and click counts can continue to rise after the broadcast reaches sent.
To collect opens and clicks, enable the corresponding tracking settings on the sending domain. For individual message events, use delivery webhooks.
Handle unsubscribes
Every broadcast email includes List-Unsubscribe with a signed, per-contact link and List-Unsubscribe-Post to support a mail client’s one-click unsubscribe action. The signature prevents someone from changing the link to target a different contact. The link does not expire.
Opening it in a browser displays a confirmation button and does not unsubscribe anyone. This prevents mailbox scanners from opting people out when they inspect links. The opt-out occurs when the recipient presses the button or the mail client submits the unsubscribe action. Reusing the link has no additional effect.
An unsubscribe makes both of these changes:
- It sets the contact’s
unsubscribedflag, excluding that contact from later broadcasts to the audience. - It adds the email address to the product’s suppression list with reason
unsubscribe. This blocks mail to the address across all audiences and transactional email, including receipts and password resets.
If the recipient asks to subscribe again:
- Remove the address from Mail → Suppressions or call
mail_suppression_remove. - Clear the contact’s
unsubscribedflag withmail_contact_update. - Read the contact back and check
mail_suppression_list. Confirm the contact is subscribed and the address is no longer suppressed. Both changes are needed before the contact can receive broadcasts again.
Next steps
- Identify a visitor: connect a visitor’s activity to a known email address.
- Read the attribution reports: use the email channel, identified by
utm_medium=email, when reviewing revenue attribution. - Send a message: send individual transactional emails.
- Set up a sending domain: configure the domain used by your
fromaddress. - Handle bounces and protect your sending: manage suppressions and sender reputation.