Sending
Sending onto an existing thread
Passthread_id and the message joins that conversation — no inbound message required. This is how an agent chases something it promised last week:
Replying
to is optional. By default the reply goes to the parent’s Reply-To (falling back to its From). Pass reply_all: true to include everyone on the original to and cc, minus the inbox itself.
There is no cap on replies per conversation.
Forwarding
Reading messages
/raw returns the original MIME source, byte for byte, when it was retained.
The message object
Labels
PATCH /v0/inboxes/{inbox_id}/messages/{message_id} sets labels. The service applies a few itself:
The
auto-reply label is the one to check before your agent answers. Replying to an out-of-office generates another out-of-office, and two automated systems will happily do that to each other for as long as you let them.
Threads
messages array in order, which is what you want when assembling context for a model.
participants has sub-address tags stripped, so [email protected] appears as [email protected] and a thread does not look like it has a new participant every time someone replies.
Searching
q is required; omitting it returns 422.
How threading works
Getting a reply onto the right conversation is the hard part of agent email, and it drives the design. Two obvious signals are both unreliable. Message-ID is assigned by the sending provider, and some providers — Cloudflare included — refuse to let you set it and do not report the one they chose, so a sent message cannot always contribute its own id to the chain. Subject and References get rewritten, stripped or dropped by real mail clients. So resolution runs in layers, strongest signal first:1
Reply-To thread token
Outbound mail carries
Reply-To: [email protected]. The +tag routes to the same inbox, so it costs no extra DNS or configuration, and it survives any subject edit. The tag is HMAC-signed, so a guessed or tampered token is rejected rather than filing mail onto someone else’s thread.2
In-Reply-To and References
Matched against stored message ids, for clients that preserve them.
3
Normalized subject plus participant overlap
Within a time window.
Re: Fwd: RE: Invoice normalizes to invoice.4
New thread
If nothing matches, a new thread is created rather than guessing.
message.received event carries a matched_by field naming which layer resolved it (token, references, subject or new), so a threading problem is diagnosable from your event log rather than being a mystery. It travels on the event, not on the stored message.

