rfc-8621

The JSON Meta Application Protocol (JMAP) for Mail

N. Jenkins, C. Newman
date2019-08 streamIETF areaart wgjmap statusPROPOSED STANDARD pages108 canonicalhttps://www.rfc-editor.org/rfc/rfc8621 doi10.17487/RFC8621
This document specifies a data model for synchronising email data with a server using the JSON Meta Application Protocol (JMAP). Clients can use this to efficiently search, access, organise, and send messages, and to get push notifications for fast resynchronisation when new messages are delivered or a change is made in another client.

updates

Extracted elements (32)

design-rationale §4.1

The Email object provides three flat body part lists (textBody, htmlBody, attachments) alongside the full bodyStructure MIME tree because flattening MIME for presentation is complex, error-prone, and causes inconsistency between clients. Standardizing this decomposition server-side reduces client implementation burden and improves consistency.

email, json

design-rationale §1.3.1

The 'maxSizeAttachmentsPerEmail' capability uses unencoded attachment sizes (as seen on disk) rather than encoded MIME sizes because users understand and are marketed to with unencoded sizes. This allows clients to enforce the limit in terms the user already understands, even though the actual MIME message may be larger due to base64 encoding.

email, json

design-rationale §1.5

The separate 'EmailDelivery' push type exists so battery-constrained clients can register for new-message notifications only, avoiding wake-ups for state changes such as marking messages read. It has no associated API methods; it exists solely as a push signal.

email, json

design-rationale §2

The unreadThreads count for the trash mailbox uses special rules: emails only in trash are excluded from other mailboxes' counts, and non-trash emails are excluded from the trash count. This treats trash emails as logically separate for unread-count purposes, matching expected client UI behavior when users delete one message from a thread.

email

interoperability-note §1.6

If the JMAP server also provides an IMAP interface and supports the IMAP Extension for Object Identifiers (RFC 8474), the ids SHOULD be the same for Mailbox, Thread, and Email objects across both protocols.

email

interoperability-note §4.1.1

JMAP Email keywords are shared with IMAP. The four IMAP system flags (\Draft, \Seen, \Flagged, \Answered) are exposed in JMAP with a '$' prefix instead of '\'. The IMAP \Recent and \Deleted keywords are not exposed via JMAP; JMAP uses a destroy model rather than IMAP's delete+expunge model.

email

interoperability-note §2

The data model is designed for concurrent IMAP (RFC 3501) and JMAP access to the same mail store. Mailbox roles are shared with IMAP SPECIAL-USE (RFC 6154), but JMAP enforces stricter constraints (at most one role per mailbox, at most one mailbox per role per account).

email

normative-requirement §2 MUST

A Mailbox MUST only have a single role, and there MUST NOT be two Mailboxes in the same account with the same role. Role values MUST be lowercase versions of names in the IANA 'IMAP Mailbox Name Attributes' registry.

email, registry

normative-requirement §2 MUST

A user may only modify the '$seen' keyword on an Email if they have 'maySetSeen' permission for ALL Mailboxes that contain that Email. Other keyword modifications require 'maySetKeywords' permission for all containing Mailboxes.

email, security

normative-requirement §2 MUST

An Email MUST belong to one or more Mailboxes at all times until it is destroyed. The Email id does not change if the Email moves between Mailboxes.

email, json

normative-requirement §4.1.1 MUST

Any message with the IMAP '\Deleted' keyword MUST NOT be visible via JMAP and must not be counted in totalEmails, unreadEmails, totalThreads, or unreadThreads Mailbox properties.

email

normative-requirement §4.2 MUST

Attempting to fetch a header field in a form forbidden for that field (e.g., 'header:From:asDate') MUST result in the method call being rejected with an 'invalidArguments' error.

email, json

normative-requirement §3 MUST

Every Email MUST belong to a Thread, even if it is the only Email in the Thread, and the threadId property is immutable. If the server merges Threads, it MUST do so by deleting and reinserting Emails that change threadId.

email, json

normative-requirement §4.1.1 MUST

Keywords MUST be returned by servers in lowercase because JSON is case-sensitive. A keyword is a case-insensitive string of 1–255 characters in ASCII subset %x21–%x7e, excluding the characters ( ) { ] % * " \.

email, json

normative-requirement §1.5 MUST

Servers MUST support JMAP push mechanisms (RFC 8620 Section 7) for all types defined in this spec. Servers implementing 'urn:ietf:params:jmap:mail' MUST support pushing state changes for the 'EmailDelivery' type; that state MUST change whenever a new Email is added to the store but SHOULD NOT change on other Email mutations.

email, json

normative-requirement §4.1.4 MUST

The Email 'preview' property MUST NOT be more than 256 characters in length. It is a server-generated plaintext fragment intended for display in message-list views.

email, json

normative-requirement §4.2 MUST

When 'maxBodyValueBytes' is non-zero, the server MUST truncate body values to that many octets and MUST ensure truncation results in valid UTF-8 and does not occur mid-codepoint. For text/html, the server SHOULD NOT truncate inside an HTML tag.

email, json

protocol-element §4.1.1

Email metadata properties include: id, blobId, threadId (all immutable, server-set), mailboxIds (Id[Boolean] map where values must be true), keywords (String[Boolean] map), size (octets of raw message), and receivedAt (UTCDate; the IMAP 'internal date').

email, json

protocol-element §4.4

Email/query supports a 'collapseThreads' Boolean argument (default false). When true, only the first Email per Thread (given the current filter and sort order) is included in the result list.

email, json

protocol-element §4.1.4

The EmailBodyPart object has properties: partId (scoped to emailId), blobId (decoded content), size (decoded octets), headers (EmailHeader[]), name (decoded filename), type (MIME type), charset, disposition, cid (Content-Id without angle brackets), language, location, and subParts (for multipart/* types).

email, json

protocol-element §2.2

The Mailbox/changes response includes an additional 'updatedProperties' field: when only totalEmails, unreadEmails, totalThreads, and/or unreadThreads changed since the old state, this lists those properties. If the server cannot determine this, it MUST return null.

email, json

protocol-element §2

The Mailbox object has properties: id (immutable, server-set), name (Net-Unicode string ≥1 char), parentId (null for top-level; forms an acyclic graph), role (IMAP special-use value in lowercase, or null), sortOrder (0 ≤ n < 2^31), totalEmails, unreadEmails, totalThreads, unreadThreads (all server-set), myRights (MailboxRights object), and isSubscribed (Boolean).

email, json

protocol-element §2

The MailboxRights object defines per-mailbox ACLs as Boolean properties: mayReadItems, mayAddItems, mayRemoveItems, maySetSeen, maySetKeywords, mayCreateChild, mayRename, mayDelete, and maySubmit. Each right maps to corresponding IMAP ACL characters (RFC 4314).

email, security

registry §10.6

This document registers new JMAP Error Codes: mailboxHasChild, mailboxHasEmail, blobNotFound, tooManyKeywords, tooManyMailboxes, invalidEmail, tooManyRecipients, noRecipients, invalidRecipients, forbiddenMailFrom, forbiddenFrom, and forbiddenToSend.

email, registry, json

registry §10.4

This document updates the IANA 'IMAP and JMAP Keywords' registry (established by RFC 5788) by registering $draft, $seen, $flagged, $answered (JMAP equivalents of IMAP system flags with '$' instead of '\'), and marking $recent as deprecated in JMAP.

email, registry

registry §10.1

Three new JMAP capability URIs are registered with IANA: 'urn:ietf:params:jmap:mail' (Mailbox, Thread, Email, SearchSnippet), 'urn:ietf:params:jmap:submission' (Identity, EmailSubmission), and 'urn:ietf:params:jmap:vacationresponse' (VacationResponse).

email, registry, json

security-consideration §9.2

Clients must take care when rendering HTML email: scripts, forms, and external resource references (including tracking pixels) must be stripped or sandboxed to protect privacy and security. Clients should warn users before loading external content.

email, security, privacy

security-consideration §9.4

Servers must validate the 'from' address of an EmailSubmission against identities the user is permitted to send as, preventing email address spoofing. Unauthorized MAIL FROM addresses should yield 'forbiddenMailFrom'; unauthorized From header addresses should yield 'forbiddenFrom'.

email, security

security-consideration §9.5

When a user has partial account access, Email objects are visible via JMAP only if the user has read permission (mayReadItems) for at least one Mailbox containing that Email. Servers must enforce Mailbox-level ACLs when returning Email data.

email, security

wire-format §4.1.3

Individual header fields are requested as properties named 'header:{field-name}[:as{Form}][:all]'. Valid parsed forms are Raw (default), Text, Addresses, GroupedAddresses, MessageIds, Date, and URLs. When both suffixes are used, they must appear in that order. Field names are matched case-insensitively.

email, json

wire-format §4.1.4

The Email 'bodyValues' property is a map of partId to EmailBodyValue objects, each with 'value' (Unicode string, CRLF normalized to LF), 'isEncodingProblem' (Boolean), and 'isTruncated' (Boolean). Text parts are decoded from Content-Transfer-Encoding and the charset specified in Content-Type.

email, json

wire-format §1.3.1

The 'urn:ietf:params:jmap:mail' accountCapabilities object must include: maxMailboxesPerEmail (UnsignedInt|null, ≥1), maxMailboxDepth (UnsignedInt|null), maxSizeMailboxName (UnsignedInt, ≥100), maxSizeAttachmentsPerEmail (UnsignedInt), emailQuerySortOptions (String[]), and mayCreateTopLevelMailbox (Boolean).

email, json