FETCH FLAGS, EXISTS and EXPUNGE updates, including while idle.
Authentication
Use an account API key with/api/e2/mailboxes/{mailboxId}/... to operate a mailbox you own. An end user can use their generated mail_… password as a Bearer token with /api/e2/mailboxes/me/.... Legacy imap_… passwords also work. The password only grants access to its own credential; it cannot manage the account.
403. Read-only credentials can list and fetch. Scope folders remain read-only with either access mode. A mailbox password used with another mailbox’s ID returns 403, and me with an account API key returns 400.
GET /mailboxes/{id} (or /mailboxes/me) returns the mailbox’s identity, scopes, controls and unread count. See Get one mailbox.
A mailbox password only works over HTTP when the credential’s protocols.api is enabled and the request comes from an address in its allowedIps; otherwise the request fails like a wrong password. With the password, /mailboxes/me/filters, /mailboxes/me/spam and /mailboxes/me/rotate-password are available only when the matching selfService setting is on. See Access and Limits.
Folders
Default folders are
INBOX, Sent, Drafts, Trash, Junk and Archive. Archive has the IMAP \Archive special-use attribute. Folder names are case-sensitive except INBOX. URL-encode the entire folder path when it contains /, for example Projects%2FInvoices.
INBOX and special-use folders can’t be renamed or deleted (400). Scopes is a reserved, non-selectable container; its children are managed from the credential’s scopes, not through folder CRUD. Renaming a custom folder also renames its descendants. Deleting a folder removes its messages from this mailbox (received mail stays in the account) and keeps its subfolders.
Create with {"path":"Projects/Invoices"} (returns 201 with the folder); an existing path returns 409. Rename with {"path":"Projects/Receipts"} or change subscriptions with {"subscribed":false} on the folder’s PATCH endpoint. Each folder in a response has path, name, specialUse, scopeId, subscribed, uidValidity, uidNext, highestModseq, total and unread. DELETE returns {"path":"Projects/Receipts","deleted":true}.
Messages and incremental sync
GET /mailboxes/{id}/folders/{folder}/messages lists messages newest UID first. limit defaults to 25 and can be at most 100. The response looks like this:
source is received for mail delivered to the account and appended for messages stored by a client, such as drafts and sent copies. Messages are identified by their UID within that folder, not by an account-level email ID. Keep the folder’s uidValidity alongside cached UIDs; discard the cache if it changes.
Use sinceUid to find newly assigned UIDs, or sinceModseq for both additions and flag changes. Incremental results are ordered by UID ascending. sinceUid alone cannot detect deletions or flag changes. The incremental response includes expunged UIDs and the folder’s highest modseq. If the server returns 409 because the checkpoint is too old, list the folder again and rebuild the cache. Expunge history is retained for approximately seven days.
For a complete incremental pass:
- Request
?sinceModseq=X&limit=100and save this first page’shighestModseqas the next checkpoint. - Process the messages and expunged UIDs. If another page is needed, keep the same
sinceModseq=Xand addsinceUid=Y, whereYis the last UID processed. Repeat until no messages remain. - Advance to the saved first-page checkpoint, not a newer value returned by a later page. Changes during paging are delivered again in the next pass.
offset is rejected for incremental requests: deletions between pages would otherwise shift offsets and skip messages. Normal full-folder listings still support offset pagination.
The list supports unread, flagged and search filters. Search covers subject and address fields for received messages, and the header block within the first 32,768 characters for appended messages; it does not scan message bodies. Fetch /messages/{uid} under the folder for parsed content, flags and the source structuredEmailId when applicable. /messages/{uid}/raw returns the RFC 822 message with Content-Type: message/rfc822. Attachment endpoints work for both received and appended messages.
Flags, moves and deletion
Patch a folder message’s flags to add, remove or replace\Seen, \Flagged, \Answered, \Draft, \Deleted and custom keywords, up to 50 per request. The response contains the message’s new flags. \Recent is server-managed and is not stored. Flags in INBOX are mirrored into its scope views; copies in other folders have independent flags.
action: "remove" to clear selected flags or action: "set" to replace the entire set. Move and copy accept {"destination":"Archive"} with the plain, unencoded folder path and return source, sourceUid, destination, destinationUid and the destination’s uidValidity. Move returns 200 and copy 201; moving a message into the folder it’s already in returns 400. Explicit expunge accepts an optional {"uids":[1,2]} selection, still limited to messages carrying \Deleted, and returns the expunged UIDs.
DELETE returns {"uid":4,"permanent":false,"trashUid":2}, with trashUid set to null when the entry was expunged.
Moving a received message into Junk marks it as junk; moving it back to INBOX marks it as not junk. That decision belongs to this credential, like its other folder state and flags; it doesn’t change the account verdict or other credentials. See Correcting a verdict.
Append drafts and other messages
POST /mailboxes/{id}/folders/{folder}/messages appends a message and returns its UID and UID validity. Supply base64-encoded raw RFC 822 content, or JSON draft fields to build a MIME message. Appending does not send email. Send with /emails or SMTP instead.
{"raw":"BASE64_RFC822","flags":["\\Draft"]}. Both forms accept an optional ISO date and flags. Without flags, JSON messages get \Seen (plus \Draft in Drafts) and raw messages get none. A JSON message’s from defaults to the credential’s sending address, or its login email. The response is 201 with folder, uid and uidValidity. Use raw MIME for attachments. List them at /messages/{uid}/attachments, then download /messages/{uid}/attachments/{index} using the returned zero-based index.
HTTP append has the same 1 MiB message limit as IMAP APPEND. Appended storage is limited to 250 MiB and 5,000 messages per account, shared by all credentials and folders. A credential can also have its own storageQuotaBytes. Quota checks are atomic across HTTP and IMAP. A message over 1 MiB returns 413 (Message is larger than 1048576 bytes), and a full quota returns 413 (Mailbox storage quota exceeded). Appending to a scope folder returns 403.
Raw messages must be valid UTF-8 without NUL bytes (ASCII MIME is also valid). Encode non-UTF-8 text and binary attachments with MIME base64 or quoted-printable before submitting. HTTP and IMAP append reject invalid UTF-8 rather than silently changing message bytes.
Sent copies
Successful immediate sends and replies authenticated with a Read & write mailbox password, including SMTP sends, save a copy to that credential’sSent. Account-key sends and replies also save copies to enabled read/write mailbox credentials whose sending address matches the authorized from address exactly, ignoring case. If no sending address is configured, the credential’s login address is its identity for this match. A domain scope alone never selects a mailbox; matching credentials must belong to the sending account. SMTP-only credentials do not save copies or select other mailboxes.
Copies with the same Message-ID in Sent are deduplicated whether the client appends its own copy before or after sending. The SMTP Sent copy preserves a valid client Message-ID. For HTTP sends, use the optional message_id field on /emails; otherwise one is generated. Message-ID remains forbidden in custom headers. SES assigns its own delivered Message-ID; the sending response still returns that delivery ID.
Scheduled sends currently do not retain the originating mailbox credential and do not save a mailbox Sent copy. message_id cannot be combined with scheduled_at.
Sent persistence runs in the background after delivery is accepted, so a successful response can precede the copy appearing. A failed, timed-out or interrupted copy is logged but is not retried, and never causes an accepted message to be resent. Each matching mailbox receives its own copy, counted against the account’s shared storage quota and that credential’s own storage quota, if set. Check available mailbox storage if a successful send has no copy. Raw Sent copies also require valid UTF-8 MIME without NUL bytes. Existing historical account-level sent emails are not backfilled into Sent.
Automatic sent copies can exceed the client APPEND limit of 1 MiB, up to the send endpoint’s message-size limit. They still count toward the same 250 MiB / 5,000-message account quota and are visible over both HTTP and IMAP.
Filters and spam settings
Each credential can sort new mail with filters at/mailboxes/{id}/filters and set its own spam level and sender lists at /mailboxes/{id}/spam. Both act on this credential’s folders only.
Existing mailbox endpoints
GET /mailboxes/{id}/messages?folder=inbox|archive|sent|junk remains available and reads INBOX, Archive, Sent or Junk. It returns messages (not data) and pagination: { limit, offset, hasMore }, and identifies messages by account email ID rather than UID. GET and PATCH /mailboxes/{id}/messages/{messageId} read and update one message, and GET /mailboxes/{id}/threads/{threadId} returns a conversation. The PATCH fields map to mailbox operations on received mail: isRead changes \Seen, isArchived moves into or out of Archive, and isJunk moves into Junk or back to INBOX, for this credential only.
There is no fallback to account-level sent_emails when Sent is empty. Use the account /emails?type=sent API for historical delivery records. This keeps HTTP and IMAP folder contents consistent. Dashboard structured_emails.is_read and account-level archive state remain separate from mailbox state.
Each message’s folder is a group: inbox (INBOX and scope folders), junk, sent (Sent, Drafts and other messages stored by clients) or archive (Archive and other folders holding received mail). folderPath has the exact folder path, so new folders don’t break strict SDK enums.
Read and archive state from before shared folders
Read and archive markers set through the HTTP API or MCP before shared folders existed are imported once by a one-off migration: messages marked read gain\Seen in INBOX and the scope folders, and archived messages move to Archive. Account-level markers don’t change. This is not ongoing synchronization with the dashboard.