Audiences & broadcasts
Create an audience, add members by address or contact, and broadcast one email to every active member from a single inbox.
Group the people you email into an audience, then send to all of them with one call. Dairo fans the broadcast out in the background and skips anyone who previously reported your mail as spam or whose address hard-bounced. Audiences are built for opted-in sending — onboarding cohorts, customer announcements, internal notices — not cold outreach.
Reading audiences uses the audiences:read scope; creating, adding members, and
deleting use audiences:write. Sending a broadcast is a send like any other —
it needs messages:send. In the Python SDK, audiences live under dairo.lists.
Create an audience
POST /v1/audiences takes a name (up to 120 characters) and an optional
description.
Add members
POST /v1/audiences/{audienceId}/members takes up to 2,000 members per
request. Each member is exactly one of:
- a raw
handle— an email address, with an optionalname, or - a
contactId— a contact whose primary email address becomes the member's address. An unknown contact is a404; a contact without an email handle is a422.
Members are upserted by address: re-adding someone updates their name and
metadata instead of creating a duplicate. The response reports how many
members the request imported.
Inspect an audience
List your audiences with GET /v1/audiences, or fetch one to see its active
members.
Send a broadcast
POST /v1/audiences/{audienceId}/send emails every active member from the
inbox you name. The body takes the same inboxId, subject, body, and
attachments fields as a single send — exactly one of
text, html, react, or a stored template — but no to, because the
recipients come from the audience. replyTo, custom headers, and tags
apply to every member's message. Fields that only make sense for one message —
to, cc, bcc, contactId, channel, sendAt, the reply-threading fields
(replyToMessageId, inReplyTo, references), and dryRun — are refused with a
400 naming the field, instead of being copied to every member or silently
dropped, and so are the Telegram-only buttons and telegram payloads. A
broadcast always sends now. Members are reached by email, so inboxId must be an
email inbox: a Telegram or Slack inbox is a 400, and an inbox that is not yours
(or not one a restricted key
is pinned to) is refused before anything is queued.
A broadcast is asynchronous. Dairo validates the request and pins the message
once — a stored template resolves at submit, so a bad template or variable is a
400 now, not a failure mid-fan-out — then returns 202 and delivers to each
member in the background:
Each member's delivery becomes its own outbound message, so bounces and complaints surface per recipient in delivery tracking.
Suppressed members are skipped. Every broadcast leaves out members who
reported your mail as spam or whose address hard-bounced, which protects your
sender reputation; they are only contacted if you deliberately pass
ignoreComplaints: true. See
Land in the inbox.
Retrying a broadcast is safe. A re-sent request with the same
Idempotency-Key — or an identical request with no key at all — de-duplicates
per recipient instead of emailing the whole audience twice. To deliberately send
the same content to the same audience again, pass a new key. See
Retries & idempotency.
Delete an audience
Deleting an audience archives it so it can no longer be sent to.
Send responsibly
- Only add people who opted in. Importing scraped or purchased addresses generates spam complaints and damages your domain's reputation for every inbox you send from.
- Review the copy before a large send. Especially for agent-written copy, have a person read the message before it goes to everyone.
- Prune addresses that bounce. Hard-bounced addresses are skipped automatically; remove them, and addresses that keep soft-bouncing, to keep the audience accurate.
Next steps
- Templates — write one email and reuse it across every broadcast.
- Webhooks — get per-recipient delivery events pushed to your app.
- API reference — every audiences endpoint, with copy-paste requests.