The basic send
CallPOST /v1/messages (scope messages:send) with an inboxId — the verified
inbox the mail comes from — at least one recipient in to, and one body. That is
a complete send.
id — it keys delivery tracking and the webhook events Dairo emits as
the mail progresses.
Dairo picks the transport automatically: external addresses go out as email, and
when every recipient is another Dairo inbox the message is delivered directly
with
channel: "a2a" — still returning sent. Pass channel to force one or
the other; see Channels.
Provide exactly one body —
text, html, react, or template. Two body
fields in one request is a 400, and so is a send with no body at all unless it
carries at least one attachment (an attachment-only email is valid). text and
html together may total at most 1 MB.Request fields
A send takes at most 50 recipients across
to, cc, and bcc combined.
Multiple recipients, CC and BCC
to, cc, and bcc each accept a single address or an array.
Send to a contact
You don’t have to know a recipient’s raw address. If you keep an address book of contacts, reference one and Dairo resolves it against the sending inbox’s channel — for an email inbox, to the contact’s primary email address. Raw addresses in the same list pass through untouched, so you can mix them freely.
A contact with no handle for the sending inbox’s channel is a
422 — resolution
never guesses an address. The resolved contact is stamped on the outbound
message, so the send joins that contact’s cross-channel history.
Send a React email
Pass areact object and Dairo renders your
React Email component into HTML — no build step or render
service on your side. Send the component source plus any props; imports are
limited to React Email components. source may be up to 64 KiB and props up
to 32 KiB of JSON.
id instead.
Attach files
Each attachment is an object, and you attach it one of two ways — never both:- Inline bytes — base64-encode the file into
contentBase64. Requires afilename;contentTypeis recommended. Best for small files. - Storage reference — pass the
objectIdof a Dairo storage object you own (the id a bucket upload returns on finalize). Dairo fetches the bytes and attaches them natively, derivingfilenameandcontentTypefrom the object; override either in the same attachment object.
413; Dairo never silently drops an attachment or edits
your body.
text or html yourself. Dairo never rewrites your message or inserts links on
its own — an attachment with delivery: "link" is rejected for exactly this
reason.
Test a send without sending it
SetdryRun: true and Dairo validates the request exactly as it would a real
send — the body rules, the recipients, the sending inbox, complaint suppression,
your attachments — resolves which channel it would go out on, and then stops.
cURL
Response
Prevent duplicate sends
Pass anidempotencyKey (or the Idempotency-Key header) and a retried request
won’t send a duplicate — Dairo returns the result of the original send instead.
Schedule for later
AddsendAt to any send and Dairo holds the email until then — useful for
reminders, drip sequences, and time-zoned announcements.
sendAt is an RFC 3339 timestamp with an explicit timezone offset (for example
2026-07-01T09:00:00-04:00, or …Z for UTC — a bare local time is a 400). It
must be in the future, at most 30 days ahead.
status: "scheduled" and the exact scheduledAt
time the email will go out, normalized to UTC.
failed. A recipient who
reported spam after you scheduled the email is still protected.
Cancel a scheduled send
While an email is stillscheduled, POST /v1/messages/{messageId}/cancel
stops it for good and sets its status to canceled. A send that is no longer
scheduled — already queued, sent, failed, or canceled — returns a 409.
Recipients who reported spam
Dairo remembers every recipient who marked your mail as spam and refuses to email them again: a send to such a recipient fails with a400 naming the
address. Set ignoreComplaints: true to override deliberately — the send then
proceeds and the response’s warnings array lists each affected recipient:
List and read your sends
List outbound messages (most recent first) withGET /v1/messages filtered on
direction: "outbound". To follow one send, use the id the send call
returned: fetch it for its current status, or list its per-recipient delivery
events.
Next steps
- Track delivery — statuses, delivery events, bounces, and complaints for every send.
- Webhooks — get delivery events pushed to your app instead of polling.
- Messages & threads — handle the replies that come back.
- Audiences & broadcasts — send one email to a whole list.