API reference

Mail

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 parameterDescription
:orgIdOrganization id (org_…).
Query parameterTypeRequiredNotes
labelsstringNoup to 100 characters

Response 200

{
  mailboxes: {
    mailboxId: string
    address: string
    domain: string
    displayName: string
    signature: string
    reminderMail: boolean
    aliases: string[]
  }[]
}
| {
  mailboxes: {
    mailboxId: string
    address: string
    domain: string
    displayName: string
    signature: string
    reminderMail: boolean
    aliases: string[]
  }[]
  labels: null | {
    mailboxId: string
    labels: {
      labelId: string
      name: string
    }[]
  }
}

GET /v1/orgs/:orgId/mail/preferences

The caller's Mail preferences in the organization: categories (the inbox's category bar on or off) and push per mailbox (all, primary or off; primary unless changed).

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).

Response 200

{
  preferences: {
    categories: boolean
    push: {
      [key: string]: "off" | "all" | "primary"
    }
  }
}

Errors

StatusMessage
403Mailboxes are only available to members.

PATCH /v1/orgs/:orgId/mail/preferences

Changes the caller's Mail preferences: categories, and push for any of their mailboxes.

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).

Request body

FieldTypeRequiredNotes
categoriesbooleanNo
pushobjectNokeys up to 100 characters; values: "all" | "primary" | "off"

Response 200

{
  preferences: {
    categories: boolean
    push: {
      [key: string]: "off" | "all" | "primary"
    }
  }
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

GET /v1/orgs/:orgId/mail/threads

All Mailboxes: one page of a view (inbox, starred, sent, drafts) across every mailbox the caller reads in the organization, newest first; each row names its mailboxId. In the inbox, category narrows it. With q, search results across those mailboxes (outside Spam and Trash, whatever the view), paged the same way. The cursor holds one position per mailbox, so pages merge without gaps or repeats; a page can be short while cursor is set.

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).
Query parameterTypeRequiredDefaultNotes
view"inbox" | "starred" | "sent" | "drafts"No"inbox"
category"primary" | "transactions" | "updates" | "promotions"No
qstringNoup to 200 characters
cursorstringNoup to 20,000 characters

Response 200

{
  threads: {
    mailboxId: string
    orgId?: string
    threadId: string
    subject: string
    snippet: string
    participants: string[]
    lastAt: number
    messageCount: number
    unreadCount: number
    starred: boolean
    labels: string[]
    box: "archive" | "trash" | "inbox" | "spam"
    hasAttachments: boolean
    category: "primary" | "transactions" | "updates" | "promotions"
    sender?: string
    draftId?: string
    snoozedUntil?: number
    sendAt?: number
  }[]
  cursor: null | string
}

Errors

StatusMessage
403Mailboxes are only available to members.

GET /v1/orgs/:orgId/mail/counts

Unread inbox conversations per category across the caller's mailboxes in the organization (counts) and for each (mailboxes), and badge: unread Primary conversations in the mailboxes they get push for, in every organization they belong to (what the Mail app shows on its icon).

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).

Response 200

{
  counts: {
    primary: number
    transactions: number
    updates: number
    promotions: number
  }
  mailboxes: {
    [key: string]: {
      primary: number
      transactions: number
      updates: number
      promotions: number
    }
  }
  badge: number
  complete: boolean
}

Errors

StatusMessage
403Mailboxes are only available to members.

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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Request body

FieldTypeRequiredNotes
signaturestringNoup to 20,000 characters
reminderMailbooleanNo

Response 200

{
  mailbox: {
    mailboxId: string
    address: string
    domain: string
    displayName: string
    signature: string
    reminderMail: boolean
    aliases: string[]
  }
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Response 200

{
  limits: {
    sendPerDay: number
    maxMessageMb: number
    maxRecipients: number
  }
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox 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. In the inbox, category (primary, transactions, updates, promotions) narrows it to one category. Each row has its category and sender. Pass cursor to continue.

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
Query parameterTypeRequiredDefaultNotes
view"inbox" | "starred" | "snoozed" | "sent" | "drafts" | "scheduled" | "archive" | "all" | "spam" | "trash" | "label"No"inbox"
labelany JSONNo
qstringNoup to 200 characters
category"primary" | "transactions" | "updates" | "promotions"No
cursorstringNoup to 2,000 characters

Response 200

{
  threads: {
    mailboxId: string
    orgId?: string
    threadId: string
    subject: string
    snippet: string
    participants: string[]
    lastAt: number
    messageCount: number
    unreadCount: number
    starred: boolean
    labels: string[]
    box: "archive" | "trash" | "inbox" | "spam"
    hasAttachments: boolean
    category: "primary" | "transactions" | "updates" | "promotions"
    sender?: string
    draftId?: string
    snoozedUntil?: number
    sendAt?: number
  }[]
  cursor: null | string
}

Errors

StatusMessage
400Choose a label.
403Mailboxes are only available to members.
404Mailbox not found

GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/counts

Unread conversations in the mailbox's inbox per category; complete is false when the inbox was too large to count whole.

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Response 200

{
  counts: {
    primary: number
    transactions: number
    updates: number
    promotions: number
  }
  complete: boolean
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

PUT /v1/orgs/:orgId/mail/mailboxes/:mailboxId/senders/:address/category

Moves a sender's mail to a category: remembered for the mailbox's later mail from them, and applied now to threadId and the sender's other conversations in the inbox. Returns how many moved.

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:addressAn email address (URL-encoded): the alias, or the forwarding address; under marketing a person's email address or mobile number.

Request body

FieldTypeRequiredNotes
category"primary" | "transactions" | "updates" | "promotions"Yes
threadIdany JSONNo

Response 200

{
  moved: number
}

Errors

StatusMessage
400Enter a valid email address.
403Mailboxes are only available to members.
404Mailbox 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Request body

FieldTypeRequiredNotes
threadIdsany JSON[]Yes1–100 items
action"archive" | "inbox" | "trash" | "spam" | "not_spam" | "delete" | "read" | "unread" | "star" | "unstar" | "label" | "unlabel" | "snooze" | "unsnooze"Yes
labelIdany JSONNo
untilintegerNo

Response 200

{
  changed: number
}

Errors

StatusMessage
400Choose a label.
400Choose when the conversation comes back.
400Move the conversation to trash first.
403Mailboxes are only available to members.
404Mailbox not found
404Label 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:threadIdConversation id (thr_…), or in Mirage a thread id (mth_…).
Query parameterTypeRequiredNotes
bodiesstringNo

Response 200

{
  thread: {
    mailboxId: string
    orgId?: string
    threadId: string
    subject: string
    snippet: string
    participants: string[]
    lastAt: number
    messageCount: number
    unreadCount: number
    starred: boolean
    labels: string[]
    box: "archive" | "trash" | "inbox" | "spam"
    hasAttachments: boolean
    category: "primary" | "transactions" | "updates" | "promotions"
    sender?: string
    draftId?: string
    snoozedUntil?: number
    sendAt?: number
  }
  messages: {
    sendAt?: number
    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" | "rejected" | "bounced" | "complained" | "sent" | "delivered" | "sending" | "delayed"
    deliveryDetail?: string
    meta: {
      unsubscribe?: {
        http?: string
        mailto?: string
        oneClick?: boolean
      }
      signedBy?: string[]
      mailedBy?: string
      arc?: string
      calendar?: string
      automated?: boolean
      origin?: {
        ip: string
        country: string
        region?: string
        city?: string
      }
    }
  }[]
}
| {
  bodies: {
    [key: string]: {
      text: string
      html?: string
      inline: {
        [key: string]: string
      }
    }
  }
  thread: {
    mailboxId: string
    orgId?: string
    threadId: string
    subject: string
    snippet: string
    participants: string[]
    lastAt: number
    messageCount: number
    unreadCount: number
    starred: boolean
    labels: string[]
    box: "archive" | "trash" | "inbox" | "spam"
    hasAttachments: boolean
    category: "primary" | "transactions" | "updates" | "promotions"
    sender?: string
    draftId?: string
    snoozedUntil?: number
    sendAt?: number
  }
  messages: {
    sendAt?: number
    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" | "rejected" | "bounced" | "complained" | "sent" | "delivered" | "sending" | "delayed"
    deliveryDetail?: string
    meta: {
      unsubscribe?: {
        http?: string
        mailto?: string
        oneClick?: boolean
      }
      signedBy?: string[]
      mailedBy?: string
      arc?: string
      calendar?: string
      automated?: boolean
      origin?: {
        ip: string
        country: string
        region?: string
        city?: string
      }
    }
  }[]
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found
404Thread 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:threadIdConversation id (thr_…), or in Mirage a thread id (mth_…).
:messageIdMessage id (msg_…; Mirage messages are mmg_…).

Response 200

{
  text: string
  html?: string
  inline: {
    [key: string]: string
  }
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found
404Message 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:threadIdConversation id (thr_…), or in Mirage a thread id (mth_…).
:messageIdMessage id (msg_…; Mirage messages are mmg_…).
:indexThe attachment's position in the message, from 0; or a Takeout archive's place in its import's files.

Response 200

{
  url: string
  filename: string
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found
404Message not found
404Attachment 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:threadIdConversation id (thr_…), or in Mirage a thread id (mth_…).
:messageIdMessage id (msg_…; Mirage messages are mmg_…).

Response 200

{
  url: string
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found
404Message not found
404No original for this message

POST /v1/orgs/:orgId/mail/mailboxes/:mailboxId/threads/:threadId/messages/:messageId/unsubscribe

Leaves the mailing list a message came from: one-click (RFC 8058) when the sender offers it, else an unsubscribe email from this mailbox; otherwise the link for the reader to open.

Auth: user access token or platform agent key · Scope: mail:send

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:threadIdConversation id (thr_…), or in Mirage a thread id (mth_…).
:messageIdMessage id (msg_…; Mirage messages are mmg_…).

Response 200

{
  done: true
  method: string
}
| {
  done: false
  url: string
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found
404Message not found
404This message has no unsubscribe link.
409This mailbox's domain was removed.
409… isn't verified for sending yet.

GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/threads/:threadId/messages/:messageId/invitation

The meeting a message carries and the event it became in this mailbox's calendars.

Auth: user access token or platform agent key · Scope: calendar:read

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:threadIdConversation id (thr_…), or in Mirage a thread id (mth_…).
:messageIdMessage id (msg_…; Mirage messages are mmg_…).

Response 200

{
  invitation: {
    timeZone: string
    recurring: boolean
    recurrenceId: null | number
    organizer: null | {
      email: string
      name?: string
    }
    attendees: number
    from: null | {
      name?: string
      email: string
    }
    event: null | {
      calendarId: string
      eventId: string
      status: "cancelled" | "confirmed" | "tentative"
      myStatus: null | "accepted" | "delegated" | "tentative" | "needs-action" | "declined"
      isOrganizer: boolean
      sequence: number
      start: number
      end: number
      allDay: boolean
    }
    startDate?: string
    endDate?: string
    method: string
    uid: string
    summary: string
    location: string
    start: number
    end: number
    allDay: boolean
  }
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found
404Message not found
404This message has no invitation.

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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Request body

FieldTypeRequiredDefaultNotes
filenamestringYes1–255 characters; trimmed
contentTypestringNo"application/octet-stream"up to 255 characters; matches ^[\w.+-]+\/[\w.+-]+$; trimmed
sizeintegerYes≥ 0

Response 201

{
  uploadId: string
  url: string
  headers: {
    "content-type": string
  }
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found
413Attachments 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Request body (up to 6 MB)

FieldTypeRequiredDefaultNotes
toobject[]No[]up to 500 items
to[].namestringNoup to 200 characters; trimmed
to[].addressstringYestrimmed; lowercased
ccobject[]No[]up to 500 items
cc[].namestringNoup to 200 characters; trimmed
cc[].addressstringYestrimmed; lowercased
bccobject[]No[]up to 500 items
bcc[].namestringNoup to 200 characters; trimmed
bcc[].addressstringYestrimmed; lowercased
subjectstringNo""up to 998 characters
htmlstringNoup to 2,000,000 characters
textstringNoup to 2,000,000 characters
attachments(object | object)[]No[]up to 50 items
replyToobjectNo
replyTo.threadIdany JSONYes
replyTo.messageIdany JSONYes
draftIdany JSONNo
sendAtintegerNo
undoSecondsintegerNo1–30

Response 201

{
  suppressed: {
    address: string
    reason: "bounce" | "complaint"
  }[]
  messageId: string
  threadId: string
  duplicate: boolean
  box?: undefined
  category: "primary" | "transactions" | "updates" | "promotions"
} | {
  suppressed: {
    address: string
    reason: "bounce" | "complaint"
  }[]
  messageId: string
  threadId: string
  duplicate: boolean
  box: "archive" | "trash" | "inbox" | "spam"
  category?: "primary" | "transactions" | "updates" | "promotions"
}

Response 202

{
  draftId: string
  threadId: string
  sendAt: number
}

Errors

StatusMessage
400Add at least one recipient.
403Mailboxes are only available to members.
404Mailbox not found
409This 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Request body

FieldTypeRequiredNotes
addressesstring[]Yesup to 500 items; each up to 254 characters

Response 200

{
  suppressed: {
    address: string
    reason: "bounce" | "complaint"
  }[]
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/recipients/suggest

Address suggestions for compose and guest fields: the organization's people (their own mailboxes, by name), then contacts, then recent correspondents.

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
Query parameterTypeRequiredDefaultNotes
qstringNo""up to 200 characters

Response 200

{
  suggestions: {
    name?: string
    address: string
    source: "recent" | "contact" | "directory"
  }[]
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Request body (up to 6 MB)

FieldTypeRequiredDefaultNotes
toobject[]No[]up to 500 items
to[].namestringNoup to 200 characters; trimmed
to[].addressstringYestrimmed; lowercased
ccobject[]No[]up to 500 items
cc[].namestringNoup to 200 characters; trimmed
cc[].addressstringYestrimmed; lowercased
bccobject[]No[]up to 500 items
bcc[].namestringNoup to 200 characters; trimmed
bcc[].addressstringYestrimmed; lowercased
subjectstringNo""up to 998 characters
htmlstringNoup to 2,000,000 characters
textstringNoup to 2,000,000 characters
attachments(object | object)[]No[]up to 50 items
replyToobjectNo
replyTo.threadIdany JSONYes
replyTo.messageIdany JSONYes

Response 201

{
  draftId: string
  threadId: string
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:draftIdDraft id: the draft's message id (msg_…).

Response 200

{
  draft: {
    failed?: string
    sendAt?: number
    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
      cid?: string
      inline?: boolean
    } | {
      threadId: string
      messageId: string
      index: number
      filename: string
      contentType: string
      size: number
      cid?: string
      inline?: boolean
    }[]
  }
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:draftIdDraft id: the draft's message id (msg_…).

Request body (up to 6 MB)

FieldTypeRequiredDefaultNotes
toobject[]No[]up to 500 items
to[].namestringNoup to 200 characters; trimmed
to[].addressstringYestrimmed; lowercased
ccobject[]No[]up to 500 items
cc[].namestringNoup to 200 characters; trimmed
cc[].addressstringYestrimmed; lowercased
bccobject[]No[]up to 500 items
bcc[].namestringNoup to 200 characters; trimmed
bcc[].addressstringYestrimmed; lowercased
subjectstringNo""up to 998 characters
htmlstringNoup to 2,000,000 characters
textstringNoup to 2,000,000 characters
attachments(object | object)[]No[]up to 50 items
replyToobjectNo
replyTo.threadIdany JSONYes
replyTo.messageIdany JSONYes

Response 200

{
  draftId: string
  threadId: string
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

DELETE /v1/orgs/:orgId/mail/mailboxes/:mailboxId/drafts/:draftId/schedule

Takes a scheduled draft off the schedule (it stays a draft).

Auth: user access token or platform agent key · Scope: mail:send

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:draftIdDraft id: the draft's message id (msg_…).

Response 204 with no body.

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:draftIdDraft id: the draft's message id (msg_…).

Response 204 with no body.

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/filters

Inbound filters: conditions on received mail, actions on its conversation.

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Response 200

{
  filters: {
    filterId: string
    match: {
      from?: string
      to?: string
      subject?: string
      words?: string
      hasAttachment?: boolean
    }
    actions: {
      labelId?: string
      archive?: boolean
      read?: boolean
      star?: boolean
      trash?: boolean
      forward?: string
    }
    enabled: boolean
  }[]
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

POST /v1/orgs/:orgId/mail/mailboxes/:mailboxId/filters

Creates an inbound filter: conditions on received mail (all must match), actions on its conversation. At most 100 per mailbox.

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Request body

FieldTypeRequiredNotes
matchobjectYes
match.fromstringNoup to 200 characters; trimmed
match.tostringNoup to 200 characters; trimmed
match.subjectstringNoup to 200 characters; trimmed
match.wordsstringNoup to 200 characters; trimmed
match.hasAttachmentbooleanNo
actionsobjectYes
actions.labelIdany JSONNo
actions.archivebooleanNo
actions.readbooleanNo
actions.starbooleanNo
actions.trashbooleanNo
actions.forwardstringNoup to 254 characters; trimmed; lowercased
enabledbooleanNo

Response 201

{
  filter: {
    filterId: string
    match: {
      from?: string
      to?: string
      subject?: string
      words?: string
      hasAttachment?: boolean
    }
    actions: {
      labelId?: string
      archive?: boolean
      read?: boolean
      star?: boolean
      trash?: boolean
      forward?: string
    }
    enabled: boolean
  }
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

PUT /v1/orgs/:orgId/mail/mailboxes/:mailboxId/filters/:filterId

Replaces a filter's conditions and actions, or turns it on or off.

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:filterIdFilter id: a mail filter (flt_…) or a saved issue filter (ifl_…).

Request body

FieldTypeRequiredNotes
matchobjectYes
match.fromstringNoup to 200 characters; trimmed
match.tostringNoup to 200 characters; trimmed
match.subjectstringNoup to 200 characters; trimmed
match.wordsstringNoup to 200 characters; trimmed
match.hasAttachmentbooleanNo
actionsobjectYes
actions.labelIdany JSONNo
actions.archivebooleanNo
actions.readbooleanNo
actions.starbooleanNo
actions.trashbooleanNo
actions.forwardstringNoup to 254 characters; trimmed; lowercased
enabledbooleanNo

Response 200

{
  filter: {
    filterId: string
    match: {
      from?: string
      to?: string
      subject?: string
      words?: string
      hasAttachment?: boolean
    }
    actions: {
      labelId?: string
      archive?: boolean
      read?: boolean
      star?: boolean
      trash?: boolean
      forward?: string
    }
    enabled: boolean
  }
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

POST /v1/orgs/:orgId/mail/mailboxes/:mailboxId/filters/:filterId/apply

Runs a filter over conversations already in the mailbox (a few seconds here, the rest in the background).

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:filterIdFilter id: a mail filter (flt_…) or a saved issue filter (ifl_…).

Response 200

{
  conversations: number
  scanned: number
  background: boolean
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

GET /v1/orgs/:orgId/mail/mailboxes/:mailboxId/forwarding

Forwarding addresses (filter action): added pending, confirmed with the code mailed to them.

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Response 200

{
  addresses: {
    address: string
    status: "pending" | "verified"
    verifiedAt?: number
  }[]
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

POST /v1/orgs/:orgId/mail/mailboxes/:mailboxId/forwarding

Adds a forwarding address (or sends a new code to a pending one): the address gets a 6-digit code by email, valid 24 hours. Needs the mailbox's domain to be active; counts toward the daily sending limit.

Auth: user access token or platform agent key · Scope: mail:send

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Request body

FieldTypeRequiredNotes
addressstringYesup to 254 characters; trimmed; lowercased

Response 201

{
  address: {
    address: string
    status: "pending"
  }
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found
409This mailbox's domain was removed.
409… isn't verified for sending yet.

POST /v1/orgs/:orgId/mail/mailboxes/:mailboxId/forwarding/verify

Confirms a forwarding address with the code it received; filters can then forward to it. Five wrong codes need a new one.

Auth: user access token or platform agent key · Scope: mail:send

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Request body

FieldTypeRequiredNotes
addressstringYesup to 254 characters; trimmed; lowercased
codestringYes4–12 characters; trimmed

Response 200

{
  address: {
    address: string
    status: "pending" | "verified"
    verifiedAt?: number
  }
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

DELETE /v1/orgs/:orgId/mail/mailboxes/:mailboxId/forwarding/:address

Removes a forwarding address; filters forwarding to it stop forwarding.

Auth: user access token or platform agent key · Scope: mail:send

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:addressAn email address (URL-encoded): the alias, or the forwarding address; under marketing a person's email address or mobile number.

Response 204 with no body.

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

DELETE /v1/orgs/:orgId/mail/mailboxes/:mailboxId/filters/:filterId

Deletes a filter. Mail already filed stays where it is.

Auth: user access token or platform agent key · Scope: mail:read

Path parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:filterIdFilter id: a mail filter (flt_…) or a saved issue filter (ifl_…).

Response 204 with no body.

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Response 200

{
  labels: {
    labelId: string
    name: string
  }[]
}

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).

Request body

FieldTypeRequiredNotes
namestringYes1–60 characters; trimmed

Response 201

{
  label: {
    labelId: string
    name: string
  }
}

Errors

StatusMessage
400A mailbox can have at most 200 labels.
403Mailboxes are only available to members.
404Mailbox not found
409A 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 parameterDescription
:orgIdOrganization id (org_…).
:mailboxIdMailbox id (mbx_…).
:labelIdLabel id (lbl_…).

Response 204 with no body.

Errors

StatusMessage
403Mailboxes are only available to members.
404Mailbox not found

GET /v1/me/mail/mailboxes

The caller's mailboxes in every organization where they read mail, each with its orgId and aliases, and those organizations (orgs: orgId, slug, name).

Auth: user access token or platform agent key

Response 200

{
  mailboxes: {
    orgId: string
    mailboxId: string
    address: string
    domain: string
    displayName: string
    signature: string
    reminderMail: boolean
    aliases: string[]
  }[]
  orgs: {
    orgId: string
    slug: string
    name: string
  }[]
}

Errors

StatusMessage
403Mailboxes are only available to members.

GET /v1/me/mail/threads

All Inboxes across organizations: one page of a view (inbox, starred, sent, drafts) across every mailbox the caller reads in every organization, newest first; each row names its mailboxId and orgId, and actions on it go to that organization's mailbox routes. In the inbox, category narrows it; with q, search results across them (outside Spam and Trash). Access is checked on every page: a mailbox the caller loses stops appearing, and one they gain starts below the rows already returned. The cursor holds one position per mailbox and the last row returned.

Auth: user access token or platform agent key

Query parameterTypeRequiredDefaultNotes
view"inbox" | "starred" | "sent" | "drafts"No"inbox"
category"primary" | "transactions" | "updates" | "promotions"No
qstringNoup to 200 characters
cursorstringNoup to 40,000 characters

Response 200

{
  threads: {
    mailboxId: string
    orgId?: string
    threadId: string
    subject: string
    snippet: string
    participants: string[]
    lastAt: number
    messageCount: number
    unreadCount: number
    starred: boolean
    labels: string[]
    box: "archive" | "trash" | "inbox" | "spam"
    hasAttachments: boolean
    category: "primary" | "transactions" | "updates" | "promotions"
    sender?: string
    draftId?: string
    snoozedUntil?: number
    sendAt?: number
  }[]
  cursor: null | string
}

Errors

StatusMessage
403Mailboxes are only available to members.

GET /v1/me/mail/counts

Unread inbox conversations per category across the caller's mailboxes in every organization (counts) and for each (mailboxes), and badge: unread Primary conversations in the mailboxes they get push for.

Auth: user access token or platform agent key

Response 200

{
  counts: {
    primary: number
    transactions: number
    updates: number
    promotions: number
  }
  mailboxes: {
    [key: string]: {
      primary: number
      transactions: number
      updates: number
      promotions: number
    }
  }
  badge: number
  complete: boolean
}

Errors

StatusMessage
403Mailboxes are only available to members.