Messages and threads
Every email sent or received by an inbox is a message. Replies are grouped into threads using the standard In-Reply-To and References headers.
The message object
| Field | Type | Description |
|---|---|---|
| id | string | Prefixed id such as msg_01jbz9c3…. |
| inbox_id, thread_id | string | The inbox it belongs to and its thread. |
| direction | "in" | "out" | Received or sent. |
| from, to, cc | string, string[] | Addresses as they appear in the headers. |
| delivered_to | string[] | For received mail, the addresses it was delivered to (the SMTP envelope). On a Catch-all this is the address the sender used. |
| subject | string | The decoded subject. |
| text, html | string | null | Body parts. Either can be null. |
| references, in_reply_to | string[], string | null | Threading headers. |
| spam | boolean | True when the spam score passed the threshold. The message is still stored. |
| auth_results | object | null | SPF, DKIM and DMARC results: pass, fail, softfail, none or temperror. |
| size_bytes | number | Size of the raw message. |
| status | string | Delivery status for sent mail; received for inbound. |
| attachments | Attachment[] | id, filename, content_type and size_bytes for each file. |
{
"id": "msg_01jbz9c3m7xq...",
"inbox_id": "ibx_01jbz8w4k2q9...",
"thread_id": "thr_01jbz9c3m7xr...",
"direction": "in",
"from": "auth@yourapp.dev",
"to": ["signup-bot@k7m3qz.mailbay.email"],
"cc": [],
"subject": "Your sign in code",
"text": "Use 482913 to finish signing in.",
"html": "<p>Use <b>482913</b> to finish signing in.</p>",
"references": [],
"in_reply_to": null,
"spam": false,
"auth_results": { "spf": "pass", "dkim": "pass", "dmarc": "pass" },
"size_bytes": 4182,
"status": "received",
"created_at": "2026-10-13T09:41:07Z",
"attachments": []
}List messages
GET/v1/inboxes/{id}/messages?limit=&cursor=
Newest first. limit is 1 to 100 and defaults to 50. Pass the next_cursor from a page to get the next one; it is null on the last page.
curl "https://api.mailbay.dev/v1/inboxes/ibx_01jbz8w4k2q9/messages?limit=20" \
-H "Authorization: Bearer $MAILBAY_API_KEY"
# {"data": [ ...messages ], "next_cursor": "msg_01jbz7..."}Wait for an email
GET/v1/inboxes/{id}/wait?from=&subject=&to=&timeout=
A long poll that returns as soon as a matching message arrives, with one time codes and links already extracted. This is how an agent finishes a sign up in two calls. from and subject match part of the sender and subject; to matches one recipient address exactly, which pairs well with the Catch-all: sign up as signup-42@k7m3qz.mailbay.email and wait for that address.
curl "https://api.mailbay.dev/v1/inboxes/ibx_01jbz8w4k2q9/wait?subject=code&timeout=60" \
-H "Authorization: Bearer $MAILBAY_API_KEY"
mailbay wait ibx_01jbz8w4k2q9 --to signup-42@k7m3qz.mailbay.email --timeout 60Threads
GET/v1/inboxes/{id}/threads
GET/v1/threads/{id}
An inbound message joins the thread of any message in the same inbox whose Message-ID appears in its In-Reply-To or References. Otherwise it starts a new thread. Replies you send set both headers, so threads hold in Gmail and Outlook. A thread returns its messages oldest first.
Raw message
GET/v1/messages/{id}/raw
Returns the original message as message/rfc822, exactly as our server received it.
not_found, never the message. See Errors.