draft-ietf-jmap-mail-10.txt   draft-ietf-jmap-mail-11.txt 
JMAP N. Jenkins JMAP N. Jenkins
Internet-Draft FastMail Internet-Draft FastMail
Updates: 5788 (if approved) C. Newman Updates: 5788 (if approved) C. Newman
Intended status: Standards Track Oracle Intended status: Standards Track Oracle
Expires: May 10, 2019 November 6, 2018 Expires: May 30, 2019 November 26, 2018
JMAP for Mail JMAP for Mail
draft-ietf-jmap-mail-10 draft-ietf-jmap-mail-11
Abstract Abstract
This document specifies a data model for synchronising email data This document specifies a data model for synchronising email data
with a server using JMAP. with a server using JMAP.
Status of This Memo Status of This Memo
This Internet-Draft is submitted in full conformance with the This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79. provisions of BCP 78 and BCP 79.
skipping to change at page 1, line 32 skipping to change at page 1, line 32
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on May 10, 2019. This Internet-Draft will expire on May 30, 2019.
Copyright Notice Copyright Notice
Copyright (c) 2018 IETF Trust and the persons identified as the Copyright (c) 2018 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of (https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
skipping to change at page 2, line 16 skipping to change at page 2, line 16
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1. Notational conventions . . . . . . . . . . . . . . . . . 4 1.1. Notational conventions . . . . . . . . . . . . . . . . . 4
1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4 1.2. Terminology . . . . . . . . . . . . . . . . . . . . . . . 4
1.3. Additions to the capabilities object . . . . . . . . . . 4 1.3. Additions to the capabilities object . . . . . . . . . . 4
1.3.1. urn:ietf:params:jmap:mail . . . . . . . . . . . . . . 4 1.3.1. urn:ietf:params:jmap:mail . . . . . . . . . . . . . . 4
1.3.2. urn:ietf:params:jmap:submission . . . . . . . . . . . 5 1.3.2. urn:ietf:params:jmap:submission . . . . . . . . . . . 5
1.3.3. urn:ietf:params:jmap:vacationresponse . . . . . . . . 6 1.3.3. urn:ietf:params:jmap:vacationresponse . . . . . . . . 6
1.4. Data type support in different accounts . . . . . . . . . 6 1.4. Data type support in different accounts . . . . . . . . . 6
1.5. Push . . . . . . . . . . . . . . . . . . . . . . . . . . 6 1.5. Push . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.6. Ids . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2. Mailboxes . . . . . . . . . . . . . . . . . . . . . . . . . . 7 2. Mailboxes . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.1. Mailbox/get . . . . . . . . . . . . . . . . . . . . . . . 10 2.1. Mailbox/get . . . . . . . . . . . . . . . . . . . . . . . 10
2.2. Mailbox/changes . . . . . . . . . . . . . . . . . . . . . 10 2.2. Mailbox/changes . . . . . . . . . . . . . . . . . . . . . 10
2.3. Mailbox/query . . . . . . . . . . . . . . . . . . . . . . 11 2.3. Mailbox/query . . . . . . . . . . . . . . . . . . . . . . 11
2.4. Mailbox/queryChanges . . . . . . . . . . . . . . . . . . 11 2.4. Mailbox/queryChanges . . . . . . . . . . . . . . . . . . 12
2.5. Mailbox/set . . . . . . . . . . . . . . . . . . . . . . . 11 2.5. Mailbox/set . . . . . . . . . . . . . . . . . . . . . . . 12
2.6. Example . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.6. Example . . . . . . . . . . . . . . . . . . . . . . . . . 12
3. Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 3. Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.1. Thread/get . . . . . . . . . . . . . . . . . . . . . . . 17 3.1. Thread/get . . . . . . . . . . . . . . . . . . . . . . . 17
3.1.1. Example . . . . . . . . . . . . . . . . . . . . . . . 17 3.1.1. Example . . . . . . . . . . . . . . . . . . . . . . . 17
3.2. Thread/changes . . . . . . . . . . . . . . . . . . . . . 17 3.2. Thread/changes . . . . . . . . . . . . . . . . . . . . . 17
4. Emails . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 4. Emails . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.1. Properties of the Email object . . . . . . . . . . . . . 18 4.1. Properties of the Email object . . . . . . . . . . . . . 18
4.1.1. Metadata . . . . . . . . . . . . . . . . . . . . . . 19 4.1.1. Metadata . . . . . . . . . . . . . . . . . . . . . . 19
4.1.2. Header fields parsed forms . . . . . . . . . . . . . 21 4.1.2. Header fields parsed forms . . . . . . . . . . . . . 21
4.1.3. Header fields properties . . . . . . . . . . . . . . 26 4.1.3. Header fields properties . . . . . . . . . . . . . . 26
skipping to change at page 4, line 50 skipping to change at page 4, line 50
SearchSnippet data types and associated API methods. The value of SearchSnippet data types and associated API methods. The value of
this property is an object which MUST contain the following this property is an object which MUST contain the following
information on server capabilities: information on server capabilities:
o *maxMailboxesPerEmail*: "PositiveInt|null" The maximum number of o *maxMailboxesPerEmail*: "PositiveInt|null" The maximum number of
mailboxes that can be can assigned to a single email. This MUST mailboxes that can be can assigned to a single email. This MUST
be an integer >= 1, or "null" for no limit (or rather, the limit be an integer >= 1, or "null" for no limit (or rather, the limit
is always the number of mailboxes in the account). is always the number of mailboxes in the account).
o *maxMailboxDepth*: "PositiveInt|null" The maximum depth of the o *maxMailboxDepth*: "PositiveInt|null" The maximum depth of the
mailbox hierarchy (i.e. one less than the maximum number of mailbox hierarchy (i.e. one more than the maximum number of
ancestors a mailbox may have), or "null" for no limit. ancestors a mailbox may have), or "null" for no limit.
o *maxSizeMailboxName*: "PositiveInt" The maximum length, in (UTF-8) o *maxSizeMailboxName*: "PositiveInt" The maximum length, in (UTF-8)
octets, allowed for the name of a mailbox. This MUST be >= 255. octets, allowed for the name of a mailbox. This MUST be at least
100, although it is recommended servers allow more.
o *maxSizeAttachmentsPerEmail*: "PositiveInt" The maximum total size o *maxSizeAttachmentsPerEmail*: "PositiveInt" The maximum total size
of attachments, in octets, allowed for a single email. A server of attachments, in octets, allowed for a single email. A server
MAY still reject import or creation of emails with a lower MAY still reject import or creation of emails with a lower
attachment size total (for example, if the body includes several attachment size total (for example, if the body includes several
megabytes of text, causing the size of the encoded MIME structure megabytes of text, causing the size of the encoded MIME structure
to be over some server-defined limit). Note, this limit is for to be over some server-defined limit). Note, this limit is for
the sum of unencoded attachment sizes. Users are generally not the sum of unencoded attachment sizes. Users are generally not
knowledgeable about encoding overhead etc., nor should they need knowledgeable about encoding overhead etc., nor should they need
to be, so marketing and help materials normally tell them the "max to be, so marketing and help materials normally tell them the "max
skipping to change at page 5, line 51 skipping to change at page 5, line 52
o *maxDelayedSend*: "PositiveInt" The number in seconds of the o *maxDelayedSend*: "PositiveInt" The number in seconds of the
maximum delay the server supports in sending (see the maximum delay the server supports in sending (see the
EmailSubmission object description). This is "0" if the server EmailSubmission object description). This is "0" if the server
does not support delayed send. does not support delayed send.
o *submissionExtensions*: "String[String[]]" A JMAP implementation o *submissionExtensions*: "String[String[]]" A JMAP implementation
that talks to a Submission [RFC6409] server SHOULD have a that talks to a Submission [RFC6409] server SHOULD have a
configuration setting that allows an administrator to expose a new configuration setting that allows an administrator to expose a new
submission EHLO capability in this field. This allows a JMAP submission EHLO capability in this field. This allows a JMAP
server to gain access to a new submission extension without code server to gain access to a new submission extension without code
changes. By default, the JMAP server should show only known safe- changes. By default, the JMAP server should hide EHLO
to-expose EHLO capabilities in this field, and hide EHLO capabilities that are to do with the transport mechanism and thus
capabilities that are only relevant to the JMAP server. Each key are only relevant to the JMAP server (for example PIPELINING,
in the object is the _ehlo-name_, and the value is a list of CHUNKING, or STARTTLS). Each key in the object is the _ehlo-
_ehlo-args_. Examples of safe-to-expose Submission extensions name_, and the value is a list of _ehlo-args_. Examples of
include: Submission extensions to include:
* FUTURERELEASE ([RFC4865]) * FUTURERELEASE ([RFC4865])
* SIZE ([RFC1870]) * SIZE ([RFC1870])
* DSN ([RFC3461]) * DSN ([RFC3461])
* DELIVERYBY ([RFC2852]) * DELIVERYBY ([RFC2852])
* MT-PRIORITY ([RFC6710]) * MT-PRIORITY ([RFC6710])
skipping to change at page 7, line 14 skipping to change at page 7, line 14
In addition, servers MUST support a psuedo-type called In addition, servers MUST support a psuedo-type called
"EmailDelivery" in the push mechanisms. The state string for this "EmailDelivery" in the push mechanisms. The state string for this
MUST change whenever a new Email is added to the store, but SHOULD MUST change whenever a new Email is added to the store, but SHOULD
NOT change upon any other change to the Email objects. NOT change upon any other change to the Email objects.
Clients in battery constrained environments may wish to delay Clients in battery constrained environments may wish to delay
fetching changes initiated by the user, but fetch new messages fetching changes initiated by the user, but fetch new messages
immediately so they can notify the user. immediately so they can notify the user.
1.6. Ids
If a JMAP Mail server also provides an IMAP interface to the data and
supports [RFC8474] IMAP Extension for Object Identifiers, the ids
SHOULD be the same for mailbox, thread, and email objects in JMAP.
2. Mailboxes 2. Mailboxes
A mailbox represents a named set of emails. This is the primary A mailbox represents a named set of emails. This is the primary
mechanism for organising emails within an account. It is analogous mechanism for organising emails within an account. It is analogous
to a folder or a label in other systems. A mailbox may perform a to a folder or a label in other systems. A mailbox may perform a
certain role in the system; see below for more details. certain role in the system; see below for more details.
For compatibility with IMAP, an email MUST belong to one or more For compatibility with IMAP, an email MUST belong to one or more
mailboxes. The email id does not change if the email changes mailboxes. The email id does not change if the email changes
mailboxes. mailboxes.
A *Mailbox* object has the following properties: A *Mailbox* object has the following properties:
o *id*: "String" (immutable; server-set) The id of the mailbox. o *id*: "Id" (immutable; server-set) The id of the mailbox.
o *name*: "String" User-visible name for the mailbox, e.g. "Inbox". o *name*: "String" User-visible name for the mailbox, e.g. "Inbox".
This may be any Net-Unicode string ([RFC5198]) of at least 1 This may be any Net-Unicode string ([RFC5198]) of at least 1
character in length, subject to the maximum size given in the character in length, subject to the maximum size given in the
capability object. Servers MUST forbid sibling Mailboxes with the capability object. Servers MUST forbid sibling Mailboxes with the
same name. Servers MAY reject names that violate server policy same name. Servers MAY reject names that violate server policy
(e.g., names containing slash (/) or control characters). (e.g., names containing slash (/) or control characters).
o *parentId*: "String|null" (default: null) The mailbox id for the o *parentId*: "Id|null" (default: null) The mailbox id for the
parent of this mailbox, or "null" if this mailbox is at the top parent of this mailbox, or "null" if this mailbox is at the top
level. Mailboxes form acyclic graphs (forests) directed by the level. Mailboxes form acyclic graphs (forests) directed by the
child-to-parent relationship. There MUST NOT be a loop. child-to-parent relationship. There MUST NOT be a loop.
o *role*: "String|null" (default: null) Identifies mailboxes that o *role*: "String|null" (default: null) Identifies mailboxes that
have a particular common purpose (e.g. the "inbox"), regardless of have a particular common purpose (e.g. the "inbox"), regardless of
the _name_ (which may be localised). This value is shared with the _name_ (which may be localised). This value is shared with
IMAP (exposed in IMAP via the [RFC6154] SPECIAL-USE extension). IMAP (exposed in IMAP via the [RFC6154] SPECIAL-USE extension).
However, unlike in IMAP, a mailbox may only have a single role, However, unlike in IMAP, a mailbox may only have a single role,
and no two mailboxes in the same account may have the same role. and no two mailboxes in the same account may have the same role.
skipping to change at page 10, line 19 skipping to change at page 10, line 25
stored separately per-user where multiple users have access to a stored separately per-user where multiple users have access to a
shared mailbox. A user may have permission to access a large shared mailbox. A user may have permission to access a large
number of shared accounts, or a shared account with a very large number of shared accounts, or a shared account with a very large
set of mailboxes, but only be interested in the contents of a few set of mailboxes, but only be interested in the contents of a few
of these. Clients may choose only to display mailboxes to the of these. Clients may choose only to display mailboxes to the
user that have the "isSubscribed" property set to "true", and user that have the "isSubscribed" property set to "true", and
offer a separate UI to allow the user to see and subscribe/ offer a separate UI to allow the user to see and subscribe/
unsubscribe from the full set of mailboxes. However, clients MAY unsubscribe from the full set of mailboxes. However, clients MAY
choose to ignore this property, either entirely for ease of choose to ignore this property, either entirely for ease of
implementation, or just for the primary account (which is normally implementation, or just for the primary account (which is normally
the user's own, rather than a shared account). the user's own, rather than a shared account). This property
corresponds to IMAP mailbox subscriptions.
For IMAP compatibility, an email in both the Trash and another For IMAP compatibility, an email in both the Trash and another
mailbox SHOULD be treated by the client as existing in both places mailbox SHOULD be treated by the client as existing in both places
(i.e. when emptying the trash, the client SHOULD just remove the (i.e. when emptying the trash, the client SHOULD just remove the
Trash mailbox and leave it in the other mailbox). Trash mailbox and leave it in the other mailbox).
The following JMAP methods are supported: The following JMAP methods are supported:
2.1. Mailbox/get 2.1. Mailbox/get
skipping to change at page 11, line 7 skipping to change at page 11, line 15
Since counts frequently change but other properties are generally Since counts frequently change but other properties are generally
only changed rarely, the server can help the client optimise data only changed rarely, the server can help the client optimise data
transfer by keeping track of changes to email/thread counts transfer by keeping track of changes to email/thread counts
separately to other state changes. The _updatedProperties_ array may separately to other state changes. The _updatedProperties_ array may
be used directly via a back-reference in a subsequent Mailbox/get be used directly via a back-reference in a subsequent Mailbox/get
call in the same single request so only these properties are returned call in the same single request so only these properties are returned
if nothing else has changed. if nothing else has changed.
2.3. Mailbox/query 2.3. Mailbox/query
Standard "/query" method. Standard "/query" method, but with the following additional argument:
o *sortAsTree*: "Boolean" (default: false) If "true", when sorting
the query results and comparing two mailboxes a and b:
* If a is an ancestor of b, it always comes first regardless of
the _sort_ comparators. Similarly, if a is descendant of b,
then b always comes first.
* Otherwise, if a and b do not share a _parentId_, find the
nearest ancestors of each that do have the same _parentId_ and
compare the sort properties on those mailboxes instead.
The result of this is that the mailboxes are sorted as a tree
according to the parentId properties, with each set of children
with a common parent sorted according to the standard sort
comparators.
o *filterAsTree*: "Boolean" (default: false) If "true", a mailbox is
only included in the query if all its ancestors are also included
in the query according to the filter.
A *FilterCondition* object has the following properties, any of which A *FilterCondition* object has the following properties, any of which
may be omitted: may be omitted:
o *parentId*: "String|null" The Mailbox _parentId_ property must o *parentId*: "Id|null" The Mailbox _parentId_ property must match
match the given value exactly. the given value exactly.
o *name*: "String" The Mailbox _name_ property contains the given o *name*: "String" The Mailbox _name_ property contains the given
string. string.
o *role*: "String|null" The Mailbox _role_ property must match the o *role*: "String|null" The Mailbox _role_ property must match the
given value exactly. given value exactly.
o *hasAnyRole*: "Boolean" If "true", a Mailbox matches if it has any o *hasAnyRole*: "Boolean" If "true", a Mailbox matches if it has any
non-"null" value for its _role_ property. non-"null" value for its _role_ property.
skipping to change at page 11, line 38 skipping to change at page 12, line 19
A Mailbox object matches the filter if and only if all of the given A Mailbox object matches the filter if and only if all of the given
conditions given match. If zero properties are specified, it is conditions given match. If zero properties are specified, it is
automatically "true" for all objects. automatically "true" for all objects.
The following properties MUST be supported for sorting: The following properties MUST be supported for sorting:
o "sortOrder" o "sortOrder"
o "name" o "name"
o "parent/name": This is a pseudo-property, just for sorting, with
the following semantics: if two mailboxes have a common parent,
sort them by name. Otherwise, find the nearest ancestors of each
that share a common parent and sort by their names instead. (i.e.
This sorts the mailbox list in alphabetical tree order).
2.4. Mailbox/queryChanges 2.4. Mailbox/queryChanges
Standard "/queryChanges" method. Standard "/queryChanges" method.
2.5. Mailbox/set 2.5. Mailbox/set
Standard "/set" method, but with the following additional argument: Standard "/set" method, but with the following additional argument:
o *onDestroyRemoveMessages*: "Boolean" (default: false) If "false", o *onDestroyRemoveMessages*: "Boolean" (default: false) If "false",
any attempt to destroy a mailbox that still has messages in it any attempt to destroy a mailbox that still has messages in it
skipping to change at page 17, line 5 skipping to change at page 17, line 5
receive two emails in the same thread but without headers that receive two emails in the same thread but without headers that
associate them with each other. The arrival of a third email in the associate them with each other. The arrival of a third email in the
thread may provide the missing references to join them all together thread may provide the missing references to join them all together
into a single thread. Since the _threadId_ of an email is immutable, into a single thread. Since the _threadId_ of an email is immutable,
if the server wishes to merge the threads, it MUST handle this by if the server wishes to merge the threads, it MUST handle this by
deleting and reinserting (with a new email id) the emails that change deleting and reinserting (with a new email id) the emails that change
threadId. threadId.
A *Thread* object has the following properties: A *Thread* object has the following properties:
o *id*: "String" (immutable; server-set) The id of the thread. o *id*: "Id" (immutable; server-set) The id of the thread.
o *emailIds*: "String[]" (server-set) The ids of the emails in the o *emailIds*: "Id[]" (server-set) The ids of the emails in the
thread, sorted by the _receivedAt_ date of the email, oldest thread, sorted by the _receivedAt_ date of the email, oldest
first. If two emails have an identical date, the sort is server- first. If two emails have an identical date, the sort is server-
dependent but MUST be stable (sorting by id is recommended). dependent but MUST be stable (sorting by id is recommended).
The following JMAP methods are supported: The following JMAP methods are supported:
3.1. Thread/get 3.1. Thread/get
Standard "/get" method. Standard "/get" method.
skipping to change at page 19, line 25 skipping to change at page 19, line 25
bodyStructure, textBody and htmlBody. bodyStructure, textBody and htmlBody.
Due to the number of properties involved, the set of _Email_ Due to the number of properties involved, the set of _Email_
properties is specified over the following three sub-sections. properties is specified over the following three sub-sections.
4.1.1. Metadata 4.1.1. Metadata
These properties represent metadata about the [RFC5322] message, and These properties represent metadata about the [RFC5322] message, and
are not derived from parsing the message itself. are not derived from parsing the message itself.
o *id*: "String" (immutable; server-set) The id of the Email object. o *id*: "Id" (immutable; server-set) The id of the Email object.
Note, this is the JMAP object id, NOT the [RFC5322] Message-ID Note, this is the JMAP object id, NOT the [RFC5322] Message-ID
header field value. header field value.
o *blobId*: "String" (immutable; server-set) The id representing the o *blobId*: "Id" (immutable; server-set) The id representing the raw
raw octets of the [RFC5322] message. This may be used to download octets of the [RFC5322] message. This may be used to download the
the raw original message, or to attach it directly to another raw original message, or to attach it directly to another Email
Email etc. etc.
o *threadId*: "String" (immutable; server-set) The id of the Thread o *threadId*: "Id" (immutable; server-set) The id of the Thread to
to which this Email belongs. which this Email belongs.
o *mailboxIds*: "String[Boolean]" The set of Mailbox ids this email o *mailboxIds*: "Id[Boolean]" The set of Mailbox ids this email
belongs to. An email MUST belong to one or more mailboxes at all belongs to. An email MUST belong to one or more mailboxes at all
times (until it is deleted). The set is represented as an object, times (until it is deleted). The set is represented as an object,
with each key being a _Mailbox id_. The value for each key in the with each key being a _Mailbox id_. The value for each key in the
object MUST be "true". object MUST be "true".
o *keywords*: "String[Boolean]" (default: ) A set of keywords that o *keywords*: "String[Boolean]" (default: ) A set of keywords that
apply to the email. The set is represented as an object, with the apply to the email. The set is represented as an object, with the
keys being the _keywords_. The value for each key in the object keys being the _keywords_. The value for each key in the object
MUST be "true". Keywords are shared with IMAP. The six system MUST be "true". Keywords are shared with IMAP. The six system
keywords from IMAP are treated specially. The following four keywords from IMAP are treated specially. The following four
skipping to change at page 28, line 33 skipping to change at page 28, line 33
These properties are derived from the [RFC5322] message body and its These properties are derived from the [RFC5322] message body and its
[RFC2045] MIME entities. [RFC2045] MIME entities.
A *EmailBodyPart* object has the following properties: A *EmailBodyPart* object has the following properties:
o *partId*: "String|null" Identifies this part uniquely within the o *partId*: "String|null" Identifies this part uniquely within the
Email. This is scoped to the _emailId_ and has no meaning outside Email. This is scoped to the _emailId_ and has no meaning outside
of the JMAP Email object representation. This is "null" if, and of the JMAP Email object representation. This is "null" if, and
only if, the part is of type "multipart/*". only if, the part is of type "multipart/*".
o *blobId*: "String|null" The id representing the raw octets of the o *blobId*: "Id|null" The id representing the raw octets of the
contents of the part after decoding any _Content-Transfer- contents of the part after decoding any _Content-Transfer-
Encoding_ (as defined in [RFC2045]), or "null" if, and only if, Encoding_ (as defined in [RFC2045]), or "null" if, and only if,
the part is of type "multipart/*". Note, two parts may be the part is of type "multipart/*". Note, two parts may be
transfer-encoded differently but have the same blob id if their transfer-encoded differently but have the same blob id if their
decoded octets are identical and the server is using a secure hash decoded octets are identical and the server is using a secure hash
of the data for the blob id. of the data for the blob id.
o *size*: "PositiveInt" The size, in octets, of the raw data after o *size*: "PositiveInt" The size, in octets, of the raw data after
content transfer decoding (as referenced by the _blobId_, i.e. the content transfer decoding (as referenced by the _blobId_, i.e. the
number of octets in the file the user would download). number of octets in the file the user would download).
skipping to change at page 31, line 30 skipping to change at page 31, line 30
way, or are referenced as embedded images in one of the "text/ way, or are referenced as embedded images in one of the "text/
html" parts of the message. The server MAY set hasAttachment html" parts of the message. The server MAY set hasAttachment
based on implementation-defined or site configurable heuristics. based on implementation-defined or site configurable heuristics.
o *preview*: "String" (immutable; server-set) Up to 255 octets of o *preview*: "String" (immutable; server-set) Up to 255 octets of
plain text, summarising the message body. This is intended to be plain text, summarising the message body. This is intended to be
shown as a preview line on a mailbox listing, and may be truncated shown as a preview line on a mailbox listing, and may be truncated
when shown. The server may choose which part of the message to when shown. The server may choose which part of the message to
include in the preview; skipping quoted sections and salutations include in the preview; skipping quoted sections and salutations
and collapsing white-space can result in a more useful preview. and collapsing white-space can result in a more useful preview.
As this is derived from the message content by the server, and the
algorithm for doing so could change over time, fetching this for
an email a second time MAY return a different result. However,
the previous value is not considered incorrect, and the change
MUST NOT cause the Email object to be considered as changed by the
server.
The exact algorithm for decomposing bodyStructure into textBody, The exact algorithm for decomposing bodyStructure into textBody,
htmlBody and attachments part lists is not mandated, as this is a htmlBody and attachments part lists is not mandated, as this is a
quality-of-service implementation issue and likely to require quality-of-service implementation issue and likely to require
workarounds for malformed content discovered over time. However, the workarounds for malformed content discovered over time. However, the
following algorithm (expressed here in JavaScript) is suggested as a following algorithm (expressed here in JavaScript) is suggested as a
starting point, based on real-world experience: starting point, based on real-world experience:
function isInlineMediaType ( type ) { function isInlineMediaType ( type ) {
return type.startsWith( 'image/' ) || return type.startsWith( 'image/' ) ||
skipping to change at page 38, line 27 skipping to change at page 38, line 27
be fast to calculate when the filter consists solely of a single be fast to calculate when the filter consists solely of a single
"inMailbox" property, as it is the same as the totalEmails or "inMailbox" property, as it is the same as the totalEmails or
totalThreads properties (depending on whether collapseThreads is totalThreads properties (depending on whether collapseThreads is
true) of the associated Mailbox object. true) of the associated Mailbox object.
4.4.1. Filtering 4.4.1. Filtering
A *FilterCondition* object has the following properties, any of which A *FilterCondition* object has the following properties, any of which
may be omitted: may be omitted:
o *inMailbox*: "String" A mailbox id. An email must be in this o *inMailbox*: "Id" A mailbox id. An email must be in this mailbox
mailbox to match the condition. to match the condition.
o *inMailboxOtherThan*: "String[]" A list of mailbox ids. An email o *inMailboxOtherThan*: "Id[]" A list of mailbox ids. An email must
must be in at least one mailbox not in this list to match the be in at least one mailbox not in this list to match the
condition. This is to allow messages solely in trash/spam to be condition. This is to allow messages solely in trash/spam to be
easily excluded from a search. easily excluded from a search.
o *before*: "UTCDate" The _receivedAt_ date-time of the email must o *before*: "UTCDate" The _receivedAt_ date-time of the email must
be before this date-time to match the condition. be before this date-time to match the condition.
o *after*: "UTCDate" The _receivedAt_ date-time of the email must be o *after*: "UTCDate" The _receivedAt_ date-time of the email must be
the same or after this date-time to match the condition. the same or after this date-time to match the condition.
o *minSize*: "PositiveInt" The _size_ of the email in octets must be o *minSize*: "PositiveInt" The _size_ of the email in octets must be
skipping to change at page 44, line 49 skipping to change at page 44, line 49
For successfully created Email objects, the _created_ response For successfully created Email objects, the _created_ response
contains the _id_, _blobId_, _threadId_ and _size_ properties of the contains the _id_, _blobId_, _threadId_ and _size_ properties of the
object. object.
The following extra _SetError_ types are defined: The following extra _SetError_ types are defined:
For *create*: For *create*:
o "blobNotFound": At least one blob id given for an EmailBodyPart o "blobNotFound": At least one blob id given for an EmailBodyPart
doesn't exist. An extra _notFound_ property of type "String[]" doesn't exist. An extra _notFound_ property of type "Id[]" MUST
MUST be included in the error object containing every _blobId_ be included in the error object containing every _blobId_
referenced by an EmailBodyPart that could not be found on the referenced by an EmailBodyPart that could not be found on the
server. server.
For *create* and *update*: For *create* and *update*:
o "tooManyKeywords": The change to the email's keywords would exceed o "tooManyKeywords": The change to the email's keywords would exceed
a server-defined maximum. a server-defined maximum.
o "tooManyMailboxes": The change to the email's mailboxes would o "tooManyMailboxes": The change to the email's mailboxes would
exceed a server-defined maximum. exceed a server-defined maximum.
skipping to change at page 45, line 31 skipping to change at page 45, line 31
within an account; if the target account already has the email the within an account; if the target account already has the email the
copy will be rejected with a standard "alreadyExists" error. copy will be rejected with a standard "alreadyExists" error.
For successfully copied Email objects, the _created_ response For successfully copied Email objects, the _created_ response
contains the _id_, _blobId_, _threadId_ and _size_ properties of the contains the _id_, _blobId_, _threadId_ and _size_ properties of the
new object. new object.
4.8. Email/import 4.8. Email/import
The _Email/import_ method adds [RFC5322] messages to the set of The _Email/import_ method adds [RFC5322] messages to the set of
emails in an account. The messages must first be uploaded as files emails in an account. The messages must first be uploaded as blobs
using the standard upload mechanism. It takes the following using the standard upload mechanism. It takes the following
arguments: arguments:
o *accountId*: "String" The id of the account to use. o *accountId*: "Id" The id of the account to use.
o *ifInState*: "String|null" This is a state string as returned by o *ifInState*: "String|null" This is a state string as returned by
the _Email/get_ method. If supplied, the string must match the the _Email/get_ method. If supplied, the string must match the
current state of the account referenced by the accountId, current state of the account referenced by the accountId,
otherwise the method will be aborted and a "stateMismatch" error otherwise the method will be aborted and a "stateMismatch" error
returned. If "null", any changes will be applied to the current returned. If "null", any changes will be applied to the current
state. state.
o *emails*: "String[EmailImport]" A map of creation id (client o *emails*: "Id[EmailImport]" A map of creation id (client
specified) to EmailImport objects specified) to EmailImport objects
An *EmailImport* object has the following properties: An *EmailImport* object has the following properties:
o *blobId*: "String" The id of the blob containing the raw [RFC5322] o *blobId*: "Id" The id of the blob containing the raw [RFC5322]
message. message.
o *mailboxIds*: "String[Boolean]" The ids of the mailboxes to assign o *mailboxIds*: "Id[Boolean]" The ids of the mailboxes to assign
this email to. At least one mailbox MUST be given. this email to. At least one mailbox MUST be given.
o *keywords*: "String[Boolean]" (default: ) The keywords to apply to o *keywords*: "String[Boolean]" (default: ) The keywords to apply to
the email. the email.
o *receivedAt*: "UTCDate" (default: time of most recent Received o *receivedAt*: "UTCDate" (default: time of most recent Received
header, or time of import on server if none) The _receivedAt_ date header, or time of import on server if none) The _receivedAt_ date
to set on the email. to set on the email.
Each email to import is considered an atomic unit which may succeed Each email to import is considered an atomic unit which may succeed
or fail individually. Importing successfully creates a new email or fail individually. Importing successfully creates a new email
object from the data referenced by the blobId and applies the given object from the data referenced by the blobId and applies the given
mailboxes, keywords and receivedAt date. mailboxes, keywords and receivedAt date.
The server MAY forbid two email objects with the same exact [RFC5322] The server MAY forbid two email objects with the same exact [RFC5322]
content, or even just with the same [RFC5322] Message-ID, to coexist content, or even just with the same [RFC5322] Message-ID, to coexist
within an account. In this case, it MUST reject attempts to import within an account. In this case, it MUST reject attempts to import
an email considered a duplicate with an "alreadyExists" SetError. An an email considered a duplicate with an "alreadyExists" SetError. An
_existingId_ property of type "String" MUST be included on the error _existingId_ property of type "Id" MUST be included on the error
object with the id of the existing email. If duplicates are allowed, object with the id of the existing email. If duplicates are allowed,
the newly created Email object MUST have a separate id and the newly created Email object MUST have a separate id and
independent mutable properties to the existing object. independent mutable properties to the existing object.
If the _blobId_, _mailboxIds_, or _keywords_ properties are invalid If the _blobId_, _mailboxIds_, or _keywords_ properties are invalid
(e.g. missing, wrong type, id not found), the server MUST reject the (e.g. missing, wrong type, id not found), the server MUST reject the
import with an "invalidProperties" SetError. import with an "invalidProperties" SetError.
If the email cannot be imported because it would take the account If the email cannot be imported because it would take the account
over quota, the import should be rejected with an "overQuota" over quota, the import should be rejected with an "overQuota"
skipping to change at page 46, line 46 skipping to change at page 46, line 46
If the blob referenced is not a valid [RFC5322] message, the server If the blob referenced is not a valid [RFC5322] message, the server
MAY modify the message to fix errors (such as removing NUL octets or MAY modify the message to fix errors (such as removing NUL octets or
fixing invalid headers). If it does this, the _blobId_ on the fixing invalid headers). If it does this, the _blobId_ on the
response MUST represent the new representation and therefore be response MUST represent the new representation and therefore be
different to the _blobId_ on the EmailImport object. Alternatively, different to the _blobId_ on the EmailImport object. Alternatively,
the server MAY reject the import with an "invalidEmail" SetError. the server MAY reject the import with an "invalidEmail" SetError.
The response has the following arguments: The response has the following arguments:
o *accountId*: "String" The id of the account used for this call. o *accountId*: "Id" The id of the account used for this call.
o *oldState*: "String|null" The state string that would have been o *oldState*: "String|null" The state string that would have been
returned by _Email/get_ on this account before making the returned by _Email/get_ on this account before making the
requested changes, or "null" if the server doesn't know what the requested changes, or "null" if the server doesn't know what the
previous state string was. previous state string was.
o *newState*: "String" The state string that will now be returned by o *newState*: "String" The state string that will now be returned by
_Email/get_ on this account. _Email/get_ on this account.
o *created*: "String[Email]" A map of the creation id to an object o *created*: "Id[Email]|null" A map of the creation id to an object
containing the _id_, _blobId_, _threadId_ and _size_ properties containing the _id_, _blobId_, _threadId_ and _size_ properties
for each successfully imported Email. for each successfully imported Email, or "null" if none.
o *notCreated*: "String[SetError]" A map of creation id to a o *notCreated*: "Id[SetError]|null" A map of creation id to a
SetError object for each Email that failed to be created. The SetError object for each Email that failed to be created, or
possible errors are defined above. "null" if all successful. The possible errors are defined above.
The following additional errors may be returned instead of the _Foo/ The following additional errors may be returned instead of the _Foo/
copy_ response: copy_ response:
"stateMismatch": An "ifInState" argument was supplied and it does not "stateMismatch": An "ifInState" argument was supplied and it does not
match the current state. match the current state.
4.9. Email/parse 4.9. Email/parse
This method allows you to parse blobs as [RFC5322] messages to get This method allows you to parse blobs as [RFC5322] messages to get
skipping to change at page 47, line 46 skipping to change at page 47, line 46
o keywords o keywords
o receivedAt o receivedAt
The _threadId_ property of the Email MAY be present if the server can The _threadId_ property of the Email MAY be present if the server can
calculate which thread the Email would be assigned to were it to be calculate which thread the Email would be assigned to were it to be
imported. Otherwise, this too is "null" if fetched. imported. Otherwise, this too is "null" if fetched.
The _Email/parse_ method takes the following arguments: The _Email/parse_ method takes the following arguments:
o *accountId*: "String" The id of the account to use. o *accountId*: "Id" The id of the account to use.
o *blobIds*: "String[]" The ids of the blobs to parse. o *blobIds*: "Id[]" The ids of the blobs to parse.
o *properties*: "String[]" If supplied, only the properties listed o *properties*: "String[]" If supplied, only the properties listed
in the array are returned for each Email object. If omitted, in the array are returned for each Email object. If omitted,
defaults to: [ "messageId", "inReplyTo", "references", "sender", defaults to: [ "messageId", "inReplyTo", "references", "sender",
"from", "to", "cc", "bcc", "replyTo", "subject", "sentAt", "from", "to", "cc", "bcc", "replyTo", "subject", "sentAt",
"hasAttachment", "preview", "bodyValues", "textBody", "htmlBody", "hasAttachment", "preview", "bodyValues", "textBody", "htmlBody",
"attachments" ] "attachments" ]
o *bodyProperties*: "String[]" A list of properties to fetch for o *bodyProperties*: "String[]" A list of properties to fetch for
each EmailBodyPart returned. If omitted, defaults to the same each EmailBodyPart returned. If omitted, defaults to the same
skipping to change at page 48, line 38 skipping to change at page 48, line 38
truncation occurs. The server MUST ensure the truncation results truncation occurs. The server MUST ensure the truncation results
in valid UTF-8 and does not occur mid-codepoint. If the part is in valid UTF-8 and does not occur mid-codepoint. If the part is
of type "text/html", the server SHOULD NOT truncate inside an HTML of type "text/html", the server SHOULD NOT truncate inside an HTML
tag, e.g. in the middle of "<a href="https://example.com">". tag, e.g. in the middle of "<a href="https://example.com">".
There is no requirement for the truncated form to be a balanced There is no requirement for the truncated form to be a balanced
tree or valid HTML (indeed, the original source may well be tree or valid HTML (indeed, the original source may well be
neither of these things). neither of these things).
The response has the following arguments: The response has the following arguments:
o *accountId*: "String" The id of the account used for the call. o *accountId*: "Id" The id of the account used for the call.
o *parsed*: "String[Email]|null" A map of blob id to parsed Email o *parsed*: "Id[Email]|null" A map of blob id to parsed Email
representation for each successfully parsed blob, or "null" if representation for each successfully parsed blob, or "null" if
none. none.
o *notParsable*: "String[]|null" A list of ids given that o *notParsable*: "Id[]|null" A list of ids given that corresponded
corresponded to blobs that could not be parsed as emails, or to blobs that could not be parsed as emails, or "null" if none.
"null" if none.
o *notFound*: "String[]|null" A list of blob ids given that could o *notFound*: "Id[]|null" A list of blob ids given that could not be
not be found, or "null" if none. found, or "null" if none.
As specified above, parsed forms of headers may only be used on As specified above, parsed forms of headers may only be used on
appropriate header fields. Attempting to fetch a form that is appropriate header fields. Attempting to fetch a form that is
forbidden (e.g. "header:From:asDate") MUST result in the method call forbidden (e.g. "header:From:asDate") MUST result in the method call
being rejected with an "invalidArguments" error. being rejected with an "invalidArguments" error.
Where a specific header is requested as a property, the Where a specific header is requested as a property, the
capitalization of the property name in the response MUST be identical capitalization of the property name in the response MUST be identical
to that used in the request. to that used in the request.
skipping to change at page 57, line 38 skipping to change at page 57, line 38
5. Search snippets 5. Search snippets
When doing a search on a "String" property, the client may wish to When doing a search on a "String" property, the client may wish to
show the relevant section of the body that matches the search as a show the relevant section of the body that matches the search as a
preview instead of the beginning of the message, and to highlight any preview instead of the beginning of the message, and to highlight any
matching terms in both this and the subject of the email. Search matching terms in both this and the subject of the email. Search
snippets represent this data. snippets represent this data.
A *SearchSnippet* object has the following properties: A *SearchSnippet* object has the following properties:
o *emailId*: "String" The email id the snippet applies to. o *emailId*: "Id" The email id the snippet applies to.
o *subject*: "String|null" If text from the filter matches the o *subject*: "String|null" If text from the filter matches the
subject, this is the subject of the email HTML-escaped, with subject, this is the subject of the email HTML-escaped, with
matching words/phrases wrapped in "<mark></mark>" tags. If it matching words/phrases wrapped in "<mark></mark>" tags. If it
does not match, this is "null". does not match, this is "null".
o *preview*: "String|null" If text from the filter matches the o *preview*: "String|null" If text from the filter matches the
plain-text or HTML body, this is the relevant section of the body plain-text or HTML body, this is the relevant section of the body
(converted to plain text if originally HTML), HTML-escaped, with (converted to plain text if originally HTML), HTML-escaped, with
matching words/phrases wrapped in "<mark></mark>" tags. It MUST matching words/phrases wrapped in "<mark></mark>" tags. It MUST
skipping to change at page 58, line 19 skipping to change at page 58, line 19
Note, unlike most data types, a SearchSnippet DOES NOT have a Note, unlike most data types, a SearchSnippet DOES NOT have a
property called "id". property called "id".
The following JMAP method is supported: The following JMAP method is supported:
5.1. SearchSnippet/get 5.1. SearchSnippet/get
To fetch search snippets, make a call to "SearchSnippet/get". It To fetch search snippets, make a call to "SearchSnippet/get". It
takes the following arguments: takes the following arguments:
o *accountId*: "String" The id of the account to use. o *accountId*: "Id" The id of the account to use.
o *filter*: "FilterOperator|FilterCondition|null" The same filter as o *filter*: "FilterOperator|FilterCondition|null" The same filter as
passed to Email/query; see the description of this method in passed to Email/query; see the description of this method in
section 4.4 for details. section 4.4 for details.
o *emailIds*: "String[]" The ids of the emails to fetch snippets o *emailIds*: "Id[]" The ids of the emails to fetch snippets for.
for.
The response has the following arguments: The response has the following arguments:
o *accountId*: "String" The id of the account used for the call. o *accountId*: "Id" The id of the account used for the call.
o *list*: "SearchSnippet[]" An array of SearchSnippet objects for o *list*: "SearchSnippet[]" An array of SearchSnippet objects for
the requested email ids. This may not be in the same order as the the requested email ids. This may not be in the same order as the
ids that were in the request. ids that were in the request.
o *notFound*: "String[]|null" An array of email ids requested which o *notFound*: "Id[]|null" An array of email ids requested which
could not be found, or "null" if all ids were found. could not be found, or "null" if all ids were found.
Since snippets are only based on immutable properties, there is no As the search snippets are derived from the message content and the
state string or update mechanism needed. algorithm for doing so could change over time, fetching the same
snippets a second time MAY return a different result. However, the
previous value is not considered incorrect, so there is no state
string or update mechanism needed.
The following standard errors may be returned instead of the The following standard errors may be returned instead of the
_searchSnippets_ response: _searchSnippets_ response:
"requestTooLarge": The number of _emailIds_ requested by the client "requestTooLarge": The number of _emailIds_ requested by the client
exceeds the maximum number the server is willing to process in a exceeds the maximum number the server is willing to process in a
single method call. single method call.
"unsupportedFilter": The server is unable to process the given "unsupportedFilter": The server is unable to process the given
_filter_ for any reason. _filter_ for any reason.
skipping to change at page 59, line 51 skipping to change at page 59, line 51
... ...
], ],
"notFound": null "notFound": null
}, "tag-0" ]] }, "tag-0" ]]
6. Identities 6. Identities
An *Identity* object stores information about an email address (or An *Identity* object stores information about an email address (or
domain) the user may send from. It has the following properties: domain) the user may send from. It has the following properties:
o *id*: "String" (immutable; server-set) The id of the identity. o *id*: "Id" (immutable; server-set) The id of the identity.
o *name*: "String" (default: "") The "From" _name_ the client SHOULD o *name*: "String" (default: "") The "From" _name_ the client SHOULD
use when creating a new message from this identity. use when creating a new message from this identity.
o *email*: "String" (immutable) The "From" email address the client o *email*: "String" (immutable) The "From" email address the client
MUST use when creating a new message from this identity. The MUST use when creating a new message from this identity. The
value MAY alternatively be of the form "*@example.com", in which value MAY alternatively be of the form "*@example.com", in which
case the client may use any valid email address ending in case the client may use any valid email address ending in
"@example.com". "@example.com".
skipping to change at page 62, line 41 skipping to change at page 62, line 41
} }
], ],
"notFound": [] "notFound": []
}, "0" ] }, "0" ]
7. Email submission 7. Email submission
An *EmailSubmission* object represents the submission of an email for An *EmailSubmission* object represents the submission of an email for
delivery to one or more recipients. It has the following properties: delivery to one or more recipients. It has the following properties:
o *id*: "String" (immutable; server-set) The id of the email o *id*: "Id" (immutable; server-set) The id of the email submission.
submission.
o *identityId*: "String" (immutable) The id of the identity to o *identityId*: "Id" (immutable) The id of the identity to associate
associate with this submission. with this submission.
o *emailId*: "String" (immutable) The id of the email to send. The o *emailId*: "Id" (immutable) The id of the email to send. The
email being sent does not have to be a draft, for example when email being sent does not have to be a draft, for example when
"redirecting" an existing email to a different address. "redirecting" an existing email to a different address.
o *threadId*: "String" (immutable; server-set) The thread id of the o *threadId*: "Id" (immutable; server-set) The thread id of the
email to send. This is set by the server to the _threadId_ email to send. This is set by the server to the _threadId_
property of the email referenced by the _emailId_. property of the email referenced by the _emailId_.
o *envelope*: "Envelope|null" (immutable) Information for use when o *envelope*: "Envelope|null" (immutable) Information for use when
sending via SMTP. An *Envelope* object has the following sending via SMTP. An *Envelope* object has the following
properties: properties:
* *mailFrom*: "Address" The email address to use as the return * *mailFrom*: "Address" The email address to use as the return
address in the SMTP submission, plus any parameters to pass address in the SMTP submission, plus any parameters to pass
with the MAIL FROM address. The JMAP server MAY allow the with the MAIL FROM address. The JMAP server MAY allow the
skipping to change at page 66, line 41 skipping to change at page 66, line 38
+ "yes": The recipient's system claims the email content has + "yes": The recipient's system claims the email content has
been displayed to the recipient. Note, there is no been displayed to the recipient. Note, there is no
guarantee that the recipient has noticed, read, or guarantee that the recipient has noticed, read, or
understood the content. understood the content.
If an MDN is received for this recipient with Disposition-Type If an MDN is received for this recipient with Disposition-Type
(as per [RFC3798] section 3.2.6.2) equal to "displayed", this (as per [RFC3798] section 3.2.6.2) equal to "displayed", this
property SHOULD be set to "yes". The server MAY also set this property SHOULD be set to "yes". The server MAY also set this
property based on other feedback channels. property based on other feedback channels.
o *dsnBlobIds*: "String[]" (server-set) A list of blob ids for DSNs o *dsnBlobIds*: "Id[]" (server-set) A list of blob ids for DSNs
received for this submission, in order of receipt, oldest first. received for this submission, in order of receipt, oldest first.
o *mdnBlobIds*: "String[]" (server-set) A list of blob ids for MDNs o *mdnBlobIds*: "Id[]" (server-set) A list of blob ids for MDNs
received for this submission, in order of receipt, oldest first. received for this submission, in order of receipt, oldest first.
JMAP servers MAY choose not to expose DSN and MDN responses as Email JMAP servers MAY choose not to expose DSN and MDN responses as Email
objects if they correlate to a EmailSubmission object. It SHOULD objects if they correlate to a EmailSubmission object. It SHOULD
only do this if it exposes them in the _dsnBlobIds_ and _mdnblobIds_ only do this if it exposes them in the _dsnBlobIds_ and _mdnblobIds_
fields instead, and expects the user to be using clients capable of fields instead, and expects the user to be using clients capable of
fetching and displaying delivery status via the EmailSubmission fetching and displaying delivery status via the EmailSubmission
object. object.
For efficiency, a server MAY destroy EmailSubmission objects a For efficiency, a server MAY destroy EmailSubmission objects a
skipping to change at page 67, line 28 skipping to change at page 67, line 25
Standard "/changes" method. Standard "/changes" method.
7.3. EmailSubmission/query 7.3. EmailSubmission/query
Standard "/query" method. Standard "/query" method.
A *FilterCondition* object has the following properties, any of which A *FilterCondition* object has the following properties, any of which
may be omitted: may be omitted:
o *emailIds*: "String[]" The EmailSubmission _emailId_ property must o *emailIds*: "Id[]" The EmailSubmission _emailId_ property must be
be in this list to match the condition. in this list to match the condition.
o *threadIds*: "String[]" The EmailSubmission _threadId_ property o *threadIds*: "Id[]" The EmailSubmission _threadId_ property must
must be in this list to match the condition. be in this list to match the condition.
o *undoStatus*: "String" The EmailSubmission _undoStatus_ property o *undoStatus*: "String" The EmailSubmission _undoStatus_ property
must be identical to the value given to match the condition. must be identical to the value given to match the condition.
o *before*: "UTCDate" The _sendAt_ property of the EmailSubmission o *before*: "UTCDate" The _sendAt_ property of the EmailSubmission
object must be before this date-time to match the condition. object must be before this date-time to match the condition.
o *after*: "UTCDate" The _sendAt_ property of the EmailSubmission o *after*: "UTCDate" The _sendAt_ property of the EmailSubmission
object must be the same as or after this date-time to match the object must be the same as or after this date-time to match the
condition. condition.
skipping to change at page 68, line 14 skipping to change at page 68, line 13
o "sentAt" o "sentAt"
7.4. EmailSubmission/queryChanges 7.4. EmailSubmission/queryChanges
Standard "/queryChanges" method. Standard "/queryChanges" method.
7.5. EmailSubmission/set 7.5. EmailSubmission/set
Standard "/set" method, with the following two extra arguments: Standard "/set" method, with the following two extra arguments:
o *onSuccessUpdateEmail*: "String[Email]|null" A map of o *onSuccessUpdateEmail*: "Id[Email]|null" A map of _EmailSubmission
_EmailSubmission id_ to an object containing properties to update id_ to an object containing properties to update on the Email
on the Email object referenced by the EmailSubmission if the object referenced by the EmailSubmission if the create/update/
create/update/destroy succeeds. (For references to destroy succeeds. (For references to EmailSubmission creations,
EmailSubmission creations, this is equivalent to a back-reference this is equivalent to a back-reference so the id will be the
so the id will be the creation id prefixed with a "#".) creation id prefixed with a "#".)
o *onSuccessDestroyEmail*: "String[]|null" A list of o *onSuccessDestroyEmail*: "Id[]|null" A list of _EmailSubmission
_EmailSubmission ids_ for which the email with the corresponding ids_ for which the email with the corresponding emailId should be
emailId should be destroyed if the create/update/destroy succeeds. destroyed if the create/update/destroy succeeds. (For references
(For references to EmailSubmission creations, this is equivalent to EmailSubmission creations, this is equivalent to a back-
to a back-reference so the id will be the creation id prefixed reference so the id will be the creation id prefixed with a "#".)
with a "#".)
A single implicit _Email/set_ call MUST be made after all A single implicit _Email/set_ call MUST be made after all
EmailSubmission create/update/destroy requests have been processed to EmailSubmission create/update/destroy requests have been processed to
perform any changes requested in these two arguments. The response perform any changes requested in these two arguments. The response
to this MUST be returned after the _EmailSubmission/set_ response. to this MUST be returned after the _EmailSubmission/set_ response.
An email is sent by creating an EmailSubmission object. When An email is sent by creating an EmailSubmission object. When
processing each create, the server must check that the email is processing each create, the server must check that the email is
valid, and the user has sufficient authorization to send it. If the valid, and the user has sufficient authorization to send it. If the
creation succeeds, the email will be sent to the recipients given in creation succeeds, the email will be sent to the recipients given in
skipping to change at page 72, line 5 skipping to change at page 72, line 5
A vacation response automatically sends a reply to messages sent to a A vacation response automatically sends a reply to messages sent to a
particular account, to inform the original sender that their message particular account, to inform the original sender that their message
may not be read for some time. Automated message sending can produce may not be read for some time. Automated message sending can produce
undesirable behaviour. To avoid this, implementors MUST follow the undesirable behaviour. To avoid this, implementors MUST follow the
recommendations set forth in [RFC3834]. recommendations set forth in [RFC3834].
The *VacationResponse* object represents the state of vacation- The *VacationResponse* object represents the state of vacation-
response related settings for an account. It has the following response related settings for an account. It has the following
properties: properties:
o *id*: "String" (immutable; server-set) The id of the object. o *id*: "Id" (immutable; server-set) The id of the object. There is
There is only ever one vacation response object, and its id is only ever one vacation response object, and its id is
""singleton"". ""singleton"".
o *isEnabled*: "Boolean" Should a vacation response be sent if an o *isEnabled*: "Boolean" Should a vacation response be sent if an
email arrives between the _fromDate_ and _toDate_? email arrives between the _fromDate_ and _toDate_?
o *fromDate*: "UTCDate|null" If _isEnabled_ is "true" emails that o *fromDate*: "UTCDate|null" If _isEnabled_ is "true" emails that
arrive on or after this date-time should receive the user's arrive on or after this date-time should receive the user's
vacation response. If "null", the vacation response is effective vacation response. If "null", the vacation response is effective
immediately. immediately.
skipping to change at page 88, line 5 skipping to change at page 88, line 5
[RFC8314] Moore, K. and C. Newman, "Cleartext Considered Obsolete: [RFC8314] Moore, K. and C. Newman, "Cleartext Considered Obsolete:
Use of Transport Layer Security (TLS) for Email Submission Use of Transport Layer Security (TLS) for Email Submission
and Access", RFC 8314, DOI 10.17487/RFC8314, January 2018, and Access", RFC 8314, DOI 10.17487/RFC8314, January 2018,
<https://www.rfc-editor.org/info/rfc8314>. <https://www.rfc-editor.org/info/rfc8314>.
[RFC8457] Leiba, B., Ed., "IMAP "$Important" Keyword and [RFC8457] Leiba, B., Ed., "IMAP "$Important" Keyword and
"\Important" Special-Use Attribute", RFC 8457, "\Important" Special-Use Attribute", RFC 8457,
DOI 10.17487/RFC8457, September 2018, DOI 10.17487/RFC8457, September 2018,
<https://www.rfc-editor.org/info/rfc8457>. <https://www.rfc-editor.org/info/rfc8457>.
[RFC8474] Gondwana, B., Ed., "IMAP Extension for Object
Identifiers", RFC 8474, DOI 10.17487/RFC8474, September
2018, <https://www.rfc-editor.org/info/rfc8474>.
11.2. URIs 11.2. URIs
[1] https://www.iana.org/assignments/imap-mailbox-name-attributes/ [1] https://www.iana.org/assignments/imap-mailbox-name-attributes/
imap-mailbox-name-attributes.xhtml imap-mailbox-name-attributes.xhtml
[2] https://www.iana.org/assignments/imap-keywords/imap- [2] https://www.iana.org/assignments/imap-keywords/imap-
keywords.xhtml keywords.xhtml
[3] https://www.w3.org/TR/CSP3/ [3] https://www.w3.org/TR/CSP3/
 End of changes. 61 change blocks. 
98 lines changed or deleted 130 lines changed or added

This html diff was produced by rfcdiff 1.47. The latest version is available from http://tools.ietf.org/tools/rfcdiff/