Messages represent individual emails in a mailbox. List and detail endpoints return message metadata; full body content (text/HTML) is fetched from storage on detail requests. All list endpoints use cursor-based pagination.
List messages GET
GET /mailboxes/{email_address}/messages
List messages in a mailbox, newest first, with cursor pagination.
Path parameters
Parameter
Type
Description
email_address
string
Email address of the mailbox
Query parameters
Parameter
Type
Default
Description
cursor
string
—
Opaque cursor from a previous response's next_cursor
limit
integer
50
Results per page (1–100)
direction
string
—
Filter by "inbound" or "outbound". Omit for all messages
Response (200)
JSON
Code examples
cURL
Get message GET
GET /mailboxes/{email_address}/messages/{message_id}
Get a single message with its full body content (plain text and HTML).
Path parameters
Parameter
Type
Description
email_address
string
Email address of the mailbox
message_id
UUID
Unique identifier of the message
Response (200)
JSON
Code examples
cURL
Send message POST
POST /mailboxes/{email_address}/messages
Compose and send an email from a mailbox. Threading is automatically resolved from in_reply_to_message_id.
Path parameters
Parameter
Type
Description
email_address
string
Email address of the sending mailbox
Request body
Field
Type
Required
Description
recipients.to
string[]
Yes
Primary recipients (at least one)
recipients.cc
string[]
No
CC recipients
recipients.bcc
string[]
No
BCC recipients (excluded from headers, delivered separately)
subject
string
Yes
Email subject line (max 998 chars)
body_text
string
No
Plain-text body
body_html
string
No
HTML body
in_reply_to_message_id
string
No
RFC 5322 Message-ID of the email being replied to
reply_to
string
No
Optional Reply-To address. If set, recipients' mail clients route replies here instead of the sending mailbox.
attachments
object[]
No
File attachments (see below). Max total 25 MB. Some file types are rejected; the API returns a 400 with a descriptive error if one is blocked.
AttachmentUpload object:
Field
Type
Description
filename
string
File name (max 255 chars)
content_type
string
MIME type (e.g. application/pdf)
content_base64
string
Base64-encoded file content
Request example
JSON
Response (201)
Returns the created message metadata (same as a list item — body content is not included).
Error responses
Status
Description
429
Mailbox has exceeded 600 sends in the last hour. Response includes Retry-After (seconds), X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers
Code examples
cURL
Forward message POST
POST /mailboxes/{email_address}/messages/{message_id}/forward
Forward a previously stored message out from this mailbox. A forward intentionally creates a new thread — it does not chain into the original conversation, matching the default behavior of Gmail, Outlook, and Apple Mail.
Forwards count against the same send rate limits as POST /messages and fire a message.forwarded webhook event on success (not message.sent).
Path parameters
Parameter
Type
Description
email_address
string
Email address of the forwarding mailbox
message_id
UUID
UUID of the original message to forward
Request body
Field
Type
Required
Description
recipients.to
string[]
—
Primary recipients
recipients.cc
string[]
—
CC recipients
recipients.bcc
string[]
—
BCC recipients (excluded from headers, delivered separately)
mode
string
No
"inline" (default) or "wrapped". See Modes below.
subject
string
No
Override; defaults to "Fwd: " + original.subject (idempotent — won't double-prefix if the original already starts with Fwd: / Fw:). An empty or missing original subject becomes "Fwd: (no subject)". Max 998 chars.
body_text
string
No
Plain-text caller note prepended above the original body (inline) or included as a top-level note (wrapped).
body_html
string
No
HTML caller note.
additional_attachments
object[]
No
Caller-authored attachments that ride alongside the forwarded content. Same AttachmentUpload shape, rejection behaviour, and 25 MB caller cap as Send.
include_original_attachments
boolean
No
inline mode only. Default true — original attachments are re-attached as direct outbound parts. Ignored in wrapped mode (originals live inside the wrapped .eml).
reply_to
string
No
Optional Reply-To header on the forward's outer envelope. The original's Reply-To (if any) is preserved inside the wrapped MIME but is not auto-inherited.
At least one address is required across recipients.to, recipients.cc, and recipients.bcc.
Modes
inline (default) — Renders the original body inline below a Gmail-style preamble that includes From:, Date:, Subject:, To:, and Cc: from the original. Original attachments are re-attached as direct outbound parts. Lossy: inline cid: images may break, and non-trivial multipart structure is flattened.
wrapped — Attaches the original raw MIME as a single message/rfc822 part, semantically preserving all headers, body parts, attachments, and nested structure. Recipient clients either expand it inline (Gmail) or show it as a forwarded.eml attachment (Outlook). Use this for originals with inline images, calendar invites, or complex multipart. The result is semantically equivalent to the original, not byte-for-byte equivalent; DKIM-preserving forwarding is not supported in v1.
Forwarding behaviour
Attachment type rejection applies only to caller-authored attachments, not to content carried over from the original message.
Original-attachment bytes are not counted against the 25 MB caller cap. Only the 10 MB outbound limit on the final composed MIME applies to the combined output.
The forward gets a brand-new Message-ID. The original is referenced via an X-Forwarded-Message-Id header.
Filename collisions across original attachments and caller additional_attachments are deduplicated automatically (caller wins; originals get a forwarded- prefix and a numeric suffix).
Request example
JSON
Response (201)
Returns a MessageResponse — the brand-new message representing the forward (same shape as a list item; body content is not included).
Error responses
Status
Description
400
Caller attachment blocked/oversize, or final composed MIME exceeds the 10 MB outbound limit
403
Organization mismatch, contact-rule block, or unclaimed-agent recipient restriction
404
Mailbox or original message not found
422
Original message cannot be forwarded — raw content was not retained (applies only to historical inbound messages ingested before raw-MIME retention was enabled)
429
Send rate limit exceeded (same quota as POST /messages)
502
Failed to load original body or attachments from storage
Delete a message. Returns 204 No Content on success.
Path parameters
Parameter
Type
Description
email_address
string
Email address of the mailbox
message_id
UUID
Unique identifier of the message
Code examples
cURL
Download attachment GET
GET /mailboxes/{email_address}/messages/{message_id}/attachments/{filename}
Download an attachment from a message. By default, responds with a 302 redirect to a temporary download URL. Set redirect=false to get the URL as JSON instead.
Path parameters
Parameter
Type
Description
email_address
string
Email address of the mailbox
message_id
UUID
Unique identifier of the message
filename
string
Attachment filename (must match exactly with attachment_metadata[].filename)
Query parameters
Parameter
Type
Default
Description
redirect
boolean
true
true returns a 302 redirect to the download URL. false returns the URL as JSON.
Response (302) — redirect mode (default)
Redirects to a temporary download URL with a Content-Disposition: attachment header. The URL is valid for 15 minutes.
Response (200) — JSON mode
JSON
Field
Type
Description
url
string
Temporary download URL (valid for 15 minutes)
filename
string
Attachment filename
expires_in
integer
URL expiration time in seconds
Error responses
Status
Description
403
Mailbox does not belong to your organization
404
Mailbox, message, or attachment not found
Code examples
cURL
Message object
MessageResponse (list items)
Field
Type
Description
id
UUID
Unique message identifier
mailbox_id
UUID
Owning mailbox
thread_id
UUID | null
Conversation thread, if resolved
message_id
string
RFC 5322 Message-ID header value
from_address
string
Sender address
to_addresses
string[]
Primary recipients
cc_addresses
string[] | null
CC recipients
subject
string | null
Email subject line
snippet
string | null
First ~200 chars of the plain-text body
direction
string
inbound or outbound
status
string
queued, sent, delivered, bounced, failed, or received
is_read
boolean
Whether the message has been read
is_starred
boolean
Whether the message is starred
has_attachments
boolean
Whether the message has attachments
reply_to
string | null
Reply-To header (inbound: parsed from the original; outbound: caller-supplied override)
created_at
string
Creation timestamp (ISO 8601)
MessageDetailResponse (single message)
Includes all MessageResponse fields plus:
Field
Type
Description
body_text
string | null
Plain-text body
body_html
string | null
HTML body
bcc_addresses
string[] | null
BCC recipients
in_reply_to
string | null
RFC 5322 In-Reply-To header
references
string[] | null
RFC 5322 References headers
attachment_metadata
object[] | null
Attachment descriptors for each file, including filename, content type, and size