Skip to main content
POST
Broadcast an email to an email list

Authorizations

Authorization
string
header
required

Dairo API key, e.g. dairo_test_... or dairo_live_...

Path Parameters

audienceId
string<uuid>
required

Body

application/json
inboxId
string
required
to
required
text
string
required
cc
bcc
subject
string
default:""
html
string
idempotencyKey
string

Body-level idempotency key kept for current API compatibility. Prefer Idempotency-Key header for new clients.

Maximum string length: 128
attachments
object[]

Outbound send attachments. 'attachment' and safe 'auto' sends are inline; current inline API limit is 10 files, 8 MiB per file, 8 MiB total decoded bytes. 'link' is explicit and must be backed by a pre-created Dairo share link placed deliberately in text/html by the caller.

Maximum array length: 10

An outbound attachment. Provide EITHER inline bytes (contentBase64) OR a storage reference (objectId) — exactly one, never both. Inline attachments require filename and are capped at 8 MiB decoded (API Gateway JSON/base64 envelope). A storage-reference attachment names a Dairo storage object you own (the objectId returned by a bucket upload's finalize, or any owned storage object); Dairo fetches its bytes server-side and native-attaches up to 24 MiB, deriving filename and contentType from the object unless you override them here. Over 24 MiB the send fails with a 413 (create a share link and place it in the body yourself; Dairo never auto-edits the body).

react
object
template
object

Send by referencing a stored template instead of an inline body. Mutually exclusive with text, html, and react: combining a template with any inline body is a 400. The referenced version is resolved and pinned at request time; supplied variables are validated against that version's variable schema (a bad variable is a synchronous 400). When the version declares a subject template it is used unless an explicit subject is provided on the request.

sendAt
string<date-time> | null

RFC 3339 timestamp WITH an explicit timezone offset to schedule the send for a future time (max 30 days ahead). Omit to send immediately. A scheduled email starts with status scheduled and can be stopped via POST /v1/outbound-emails/{emailId}/cancel before it fires.

channel
enum<string>

Optional explicit delivery channel. "email" forces SES even when every recipient is a Dairo inbox; "a2a" requires every recipient to be a Dairo inbox (400 otherwise) and cannot combine with sendAt. Absent = auto (a2a when all recipients are internal, else email). Unknown values are a 400.

Available options:
email,
a2a
replyTo
string<email>

Optional single Reply-To address, set verbatim as the MIME Reply-To header.

headers
object

Optional custom MIME headers ({name: value}). Spoofable/provenance headers are dropped server-side; malformed names or CR/LF are rejected.

tags
object

Optional SES message tags ({name: value}), validated against SES tag constraints.

ignoreComplaints
boolean
default:false

Override complaint suppression for recipients that previously complained.

contactId
string

Optional contact reference: the contact's PRIMARY handle for the sending inbox's channel is added to to, so a send needs no raw address. Accepts a bare contact id, or a contact:<id> / @alias / @me ref. Recipients in to/cc/bcc may ALSO be contact references (@alias, contact:<id>, @me); raw addresses pass through unchanged.

buttons
object[][]

Telegram inline keyboard (Telegram-channel inbox only): rows of {text, url|callback} buttons. A URL button opens a link; a callback button surfaces the tap back to you as an inbound button_tap event and shows a feedback toast on tap (default: ✓ + the button label; set alert:true for a modal).

dryRun
boolean
default:false

Per-request dry run, at parity with the letters API's dryRun. When true the request is validated and the sending inbox resolved exactly as a real send would be, then a non-persisted MessagePreview (status "preview") is returned: nothing is created, queued, handed to the provider, metered, or billed. Absent or false is a normal send. Test mode is scoped to the REQUEST, not to the API key — an API key's environment label has no effect on delivery.

Response

Broadcast accepted for asynchronous fan-out. The dispatcher validated and pinned the body and enqueued one broadcast job; the expander worker resolves list membership and delivers per recipient off the request path (SES for external, A2A for internal Dairo inboxes). Poll delivery via GET /v1/messages / webhooks.

The 202 accept envelope for a list broadcast enqueued for asynchronous fan-out.

object
string
required
Allowed value: "broadcast"
id
string
required

The server-minted broadcast id (bcast_...).

audienceId
string<uuid>
required
status
string
required
Allowed value: "queued"