Skip to main content
Every email that reaches one of your inboxes becomes a structured message — parsed sender, subject, both bodies, attachment metadata — with no raw MIME to handle. A message that draws replies becomes a thread, so the whole conversation stays in one place. You can work with inbound mail two ways: subscribe to the message.received webhook and act the moment mail arrives, or pull messages on demand with the endpoints on this page. Every read uses the messages:read scope.

List messages

GET /v1/messages returns messages newest-first — across every inbox, or filtered to one.
direction=outbound with no channel filter returns the outbound send ledger — per-recipient delivery status, bounces, and complaints — described in Outbound tracking. That view honors inboxId and limit but not cursor or threadId; add an explicit channel, e.g. channel=email&direction=outbound, to page the message shape shown here.

Fetch one message

List rows carry a textPreview. Fetch a single message for the full record — both bodies, parsed addresses, and attachment metadata.

Message fields

Follow a conversation with threads

A thread is one conversation on an inbox: a message and the replies it collected. GET /v1/threads lists threads by most recent activity; GET /v1/threads/{threadId} returns one thread with its messages oldest-first, up to 100.

Reply in a thread

When you email someone and they answer, the reply lands in the thread of the message it answers — Dairo connects it through standard email reply headers. To continue the exchange, send from the same inbox, address the sender, and keep the subject with a Re: prefix so the recipient’s mail client keeps the conversation together.

Handle attachments

Files on inbound mail arrive as metadata only; when you need one, you mint a short-lived download link or fetch the bytes. Inbound files come from arbitrary senders, so treat them as untrusted — the endpoints and the handling rules live on Attachments.

Delete messages

POST /v1/messages/batch-delete removes up to 1,000 messages in one call and needs the messages:read scope. The response reports per-id results — an id you don’t own is returned under failed and never aborts the rest of the batch.

Next steps