API reference
Read, organize and send mail from the mailboxes you belong to.
These routes act only on mailboxes the signed-in person is a member of; keys get no mailboxes. See Mail.
GET /v1/orgs/:orgId/mail/mailboxes
The mailboxes the caller is a member of, with their aliases and signature. Keys get an empty list.
Auth: user access token or platform agent key · Scope: mail:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
Response 200
{
mailboxes: {
mailboxId: string
address: string
domain: string
displayName: string
signature: string
aliases: string[]
}[]
}PATCH /v1/orgs/:orgId/mail/mailboxes/:mailboxId/settings
Sets the mailbox's signature.
Auth: user access token or platform agent key · Scope: mail:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
signature | string | No | up to 20,000 characters |
Response 200
{
mailbox: {
mailboxId: string
address: string
domain: string
displayName: string
signature: string
aliases: string[]
}
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/limits
The organization's sending limits: messages per day, message size and recipients per message.
Auth: user access token or platform agent key · Scope: mail:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
Response 200
{
limits: {
sendPerDay: number
maxMessageMb: number
maxRecipients: number
}
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/threads
One page of conversations in a view (inbox, starred, sent, drafts, archive, all, spam, trash, or label with label), newest first, optionally matching q. Pass cursor to continue.
Auth: user access token or platform agent key · Scope: mail:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
| Query parameter | Type | Required | Default | Notes |
|---|---|---|---|---|
view | "inbox" | "starred" | "sent" | "drafts" | "archive" | "all" | "spam" | "trash" | "label" | No | "inbox" | |
label | any JSON | No | ||
q | string | No | up to 200 characters | |
cursor | string | No | up to 2,000 characters |
Response 200
{
threads: {
threadId: string
subject: string
snippet: string
participants: string[]
lastAt: number
messageCount: number
unreadCount: number
starred: boolean
labels: string[]
box: "inbox" | "archive" | "spam" | "trash"
hasAttachments: boolean
draftId?: string
}[]
cursor: null | string
}Errors
| Status | Message |
|---|---|
400 | Choose a label. |
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
POST /v1/orgs/:orgId/mail/mailboxes/:mailboxId/threads/actions
Applies one action to up to 100 conversations: archive, move to inbox, trash, spam, not spam, delete (from trash or spam only), read, unread, star, unstar, label or unlabel.
Auth: user access token or platform agent key · Scope: mail:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
threadIds | any JSON[] | Yes | 1–100 items |
action | "archive" | "inbox" | "trash" | "spam" | "not_spam" | "delete" | "read" | "unread" | "star" | "unstar" | "label" | "unlabel" | Yes | |
labelId | any JSON | No |
Response 200
{
changed: number
}Errors
| Status | Message |
|---|---|
400 | Choose a label. |
400 | Move the conversation to trash first. |
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
404 | Label not found |
GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/threads/:threadId
A conversation and its messages, without bodies.
Auth: user access token or platform agent key · Scope: mail:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
:threadId | Conversation id (thr_…). |
Response 200
{
thread: {
threadId: string
subject: string
snippet: string
participants: string[]
lastAt: number
messageCount: number
unreadCount: number
starred: boolean
labels: string[]
box: "inbox" | "archive" | "spam" | "trash"
hasAttachments: boolean
draftId?: string
}
messages: {
messageId: string
threadId: string
kind: "in" | "sent" | "draft"
from: {
name?: string
address: string
}
to: {
name?: string
address: string
}[]
cc: {
name?: string
address: string
}[]
bcc: {
name?: string
address: string
}[]
replyTo: {
name?: string
address: string
}[]
subject: string
snippet: string
at: number
unread: boolean
size: number
rfcMessageId: string
attachments: {
index: number
filename: string
contentType: string
size: number
cid?: string
inline: boolean
}[]
spam: boolean
verdicts?: {
[key: string]: string
}
deliveryStatus?: "failed" | "sent" | "sending" | "delivered" | "delayed" | "bounced" | "complained" | "rejected"
deliveryDetail?: string
}[]
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
404 | Thread not found |
GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/threads/:threadId/messages/:messageId/body
A message's text and HTML, with short-lived links for inline images. Reading a received message marks it read.
Auth: user access token or platform agent key · Scope: mail:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
:threadId | Conversation id (thr_…). |
:messageId | Message id (msg_…). |
Response 200
{
text: string
html?: string
inline: {
[key: string]: string
}
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
404 | Message not found |
GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/threads/:threadId/messages/:messageId/attachments/:index
A short-lived download link for an attachment.
Auth: user access token or platform agent key · Scope: mail:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
:threadId | Conversation id (thr_…). |
:messageId | Message id (msg_…). |
:index | The attachment's position in the message, from 0. |
Response 200
{
url: string
filename: string
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
404 | Message not found |
404 | Attachment not found |
GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/threads/:threadId/messages/:messageId/raw
A short-lived link to the original message (.eml).
Auth: user access token or platform agent key · Scope: mail:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
:threadId | Conversation id (thr_…). |
:messageId | Message id (msg_…). |
Response 200
{
url: string
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
404 | Message not found |
404 | No original for this message |
POST /v1/orgs/:orgId/mail/mailboxes/:mailboxId/uploads
Compose attachments go straight to the bucket; the link only accepts the declared size and type.
Auth: user access token or platform agent key · Scope: mail:send
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
Request body
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
filename | string | Yes | 1–255 characters; trimmed | |
contentType | string | No | "application/octet-stream" | up to 255 characters; matches ^[\w.+-]+\/[\w.+-]+$; trimmed |
size | integer | Yes | ≥ 0 |
Response 201
{
uploadId: string
url: string
headers: {
"content-type": string
}
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
413 | Attachments can be at most … MB in total. |
POST /v1/orgs/:orgId/mail/mailboxes/:mailboxId/send
Sends a message from the mailbox and files it in Sent. The domain must be verified. With replyTo, it's threaded as a reply; with draftId, the draft is removed. The response lists recipients that bounced or complained before.
Auth: user access token or platform agent key · Scope: mail:send
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
Request body (up to 6 MB)
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
to | object[] | No | [] | up to 500 items |
to[].name | string | No | up to 200 characters; trimmed | |
to[].address | string | Yes | trimmed; lowercased | |
cc | object[] | No | [] | up to 500 items |
cc[].name | string | No | up to 200 characters; trimmed | |
cc[].address | string | Yes | trimmed; lowercased | |
bcc | object[] | No | [] | up to 500 items |
bcc[].name | string | No | up to 200 characters; trimmed | |
bcc[].address | string | Yes | trimmed; lowercased | |
subject | string | No | "" | up to 998 characters |
html | string | No | up to 2,000,000 characters | |
text | string | No | up to 2,000,000 characters | |
attachments | (object | object)[] | No | [] | up to 50 items |
replyTo | object | No | ||
replyTo.threadId | any JSON | Yes | ||
replyTo.messageId | any JSON | Yes | ||
draftId | any JSON | No |
Response 201
{
suppressed: {
address: string
reason: "bounce" | "complaint"
}[]
messageId: string
threadId: string
duplicate: boolean
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
409 | This mailbox's domain was removed. |
409 | … isn't verified for sending yet. |
POST /v1/orgs/:orgId/mail/mailboxes/:mailboxId/recipients/check
Recipients that bounced or complained before, so compose can warn.
Auth: user access token or platform agent key · Scope: mail:send
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
addresses | string[] | Yes | up to 500 items; each up to 254 characters |
Response 200
{
suppressed: {
address: string
reason: "bounce" | "complaint"
}[]
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
POST /v1/orgs/:orgId/mail/mailboxes/:mailboxId/drafts
Saves a new draft.
Auth: user access token or platform agent key · Scope: mail:send
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
Request body (up to 6 MB)
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
to | object[] | No | [] | up to 500 items |
to[].name | string | No | up to 200 characters; trimmed | |
to[].address | string | Yes | trimmed; lowercased | |
cc | object[] | No | [] | up to 500 items |
cc[].name | string | No | up to 200 characters; trimmed | |
cc[].address | string | Yes | trimmed; lowercased | |
bcc | object[] | No | [] | up to 500 items |
bcc[].name | string | No | up to 200 characters; trimmed | |
bcc[].address | string | Yes | trimmed; lowercased | |
subject | string | No | "" | up to 998 characters |
html | string | No | up to 2,000,000 characters | |
text | string | No | up to 2,000,000 characters | |
attachments | (object | object)[] | No | [] | up to 50 items |
replyTo | object | No | ||
replyTo.threadId | any JSON | Yes | ||
replyTo.messageId | any JSON | Yes |
Response 201
{
draftId: string
threadId: string
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/drafts/:draftId
A draft, for editing.
Auth: user access token or platform agent key · Scope: mail:send
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
:draftId | Draft id: the draft's message id (msg_…). |
Response 200
{
draft: {
draftId: string
threadId: string
replyTo?: {
threadId: string
messageId: string
}
to: {
name?: string
address: string
}[]
cc: {
name?: string
address: string
}[]
bcc: {
name?: string
address: string
}[]
subject?: string
html?: string
text: string
attachments: {
uploadId: string
filename: string
contentType: string
size: number
} | {
threadId: string
messageId: string
index: number
filename: string
contentType: string
size: number
}[]
}
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
PUT /v1/orgs/:orgId/mail/mailboxes/:mailboxId/drafts/:draftId
Replaces a draft.
Auth: user access token or platform agent key · Scope: mail:send
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
:draftId | Draft id: the draft's message id (msg_…). |
Request body (up to 6 MB)
| Field | Type | Required | Default | Notes |
|---|---|---|---|---|
to | object[] | No | [] | up to 500 items |
to[].name | string | No | up to 200 characters; trimmed | |
to[].address | string | Yes | trimmed; lowercased | |
cc | object[] | No | [] | up to 500 items |
cc[].name | string | No | up to 200 characters; trimmed | |
cc[].address | string | Yes | trimmed; lowercased | |
bcc | object[] | No | [] | up to 500 items |
bcc[].name | string | No | up to 200 characters; trimmed | |
bcc[].address | string | Yes | trimmed; lowercased | |
subject | string | No | "" | up to 998 characters |
html | string | No | up to 2,000,000 characters | |
text | string | No | up to 2,000,000 characters | |
attachments | (object | object)[] | No | [] | up to 50 items |
replyTo | object | No | ||
replyTo.threadId | any JSON | Yes | ||
replyTo.messageId | any JSON | Yes |
Response 200
{
draftId: string
threadId: string
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
DELETE /v1/orgs/:orgId/mail/mailboxes/:mailboxId/drafts/:draftId
Discards a draft.
Auth: user access token or platform agent key · Scope: mail:send
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
:draftId | Draft id: the draft's message id (msg_…). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/labels
The mailbox's labels, by name.
Auth: user access token or platform agent key · Scope: mail:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
Response 200
{
labels: {
labelId: string
name: string
}[]
}Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
POST /v1/orgs/:orgId/mail/mailboxes/:mailboxId/labels
Creates a label. Names are unique in the mailbox, ignoring case.
Auth: user access token or platform agent key · Scope: mail:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
Request body
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | Yes | 1–60 characters; trimmed |
Response 201
{
label: {
labelId: string
name: string
}
}Errors
| Status | Message |
|---|---|
400 | A mailbox can have at most 200 labels. |
403 | Mailboxes are only available to members. |
404 | Mailbox not found |
409 | A label with this name exists. |
DELETE /v1/orgs/:orgId/mail/mailboxes/:mailboxId/labels/:labelId
Deletes a label. Conversations stop showing it.
Auth: user access token or platform agent key · Scope: mail:read
| Path parameter | Description |
|---|---|
:orgId | Organization id (org_…). |
:mailboxId | Mailbox id (mbx_…). |
:labelId | Label id (lbl_…). |
Response 204 with no body.
Errors
| Status | Message |
|---|---|
403 | Mailboxes are only available to members. |
404 | Mailbox not found |