<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.32 (Ruby 3.3.0) -->


<!DOCTYPE rfc  [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">

]>


<rfc ipr="trust200902" docName="draft-ietf-jmap-object-history-03" category="std" consensus="true" submissionType="IETF" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="JMAP Object History">JMAP Object History</title>

    <author initials="B." surname="Gondwana" fullname="Bron Gondwana">
      <organization>Fastmail</organization>
      <address>
        <email>brong@fastmailteam.com</email>
      </address>
    </author>
    <author initials="J." surname="Coffey" fullname="John Coffey">
      <organization>Coffey Labs</organization>
      <address>
        <email>john@coffeylabs.org</email>
      </address>
    </author>

    <date year="2026" month="November" day="02"/>

    
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 46?>

<t>The JMAP base protocol (RFC8620) provides methods for synchronizing
the current state of data objects between client and server.  This
extension adds the ability to retrieve historical versions of objects,
including objects that have been destroyed, by extending the standard
Foo/get method, to find destroyed objects with Foo/query, and to
restore them with Foo/set.</t>



    </abstract>



  </front>

  <middle>


<?line 55?>

<section anchor="introduction"><name>Introduction</name>

<t>JMAP (<xref target="JMAP-CORE"/> — JSON Meta Application Protocol) provides a
standard set of methods for each data type: Foo/get, Foo/changes,
Foo/set, Foo/query, and Foo/queryChanges.  These methods operate
on the current state of objects.  The Foo/changes method tells a
client which objects have changed, but does not provide the
previous values.</t>

<t>In many applications it is useful to access historical versions
of objects.  For example, a user may want to see previous versions
of a contact record (<xref target="JMAP-CONTACTS"/>) or recover a deleted
email (<xref target="JMAP-MAIL"/>).</t>

<t>This extension adds history support to the standard Foo/get
method.  When the <spanx style="verb">urn:ietf:params:jmap:object-history</spanx> capability
is included in the request's <spanx style="verb">using</spanx> array, Foo/get gains
additional parameters that allow the client to request previous
versions of objects, including objects that have been destroyed,
Foo/query can search the destroyed objects, and Foo/set can
restore them.</t>

<section anchor="conventions-used-in-this-document"><name>Conventions Used in This Document</name>

<t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>

<?line -18?>

</section>
</section>
<section anchor="addition-to-the-capabilities-object"><name>Addition to the Capabilities Object</name>

<t>The capabilities object is returned as part of the JMAP Session
object; see <xref target="JMAP-CORE"/>, Section 2.</t>

<t>This document defines an additional capability URI.</t>

<section anchor="urnietfparamsjmapobject-history"><name>urn:ietf:params:jmap:object-history</name>

<t>The capability <spanx style="verb">urn:ietf:params:jmap:object-history</spanx> being present
in the "accountCapabilities" property of an account represents
support for retrieving historical object versions in that account.
Servers that include the capability in one or more
"accountCapabilities" properties <bcp14>MUST</bcp14> also include the property in
the "capabilities" property.</t>

<t>The value of this property in the JMAP session "capabilities"
property <bcp14>MUST</bcp14> be an empty object.</t>

<t>The value of this property in an account's "accountCapabilities"
property is an object that <bcp14>MUST</bcp14> contain the following information
on server capabilities for that account:</t>

<t><list style="symbols">
  <t>maxHistoryDuration: "UnsignedInt|null"  <vspace blankLines='1'/>
The number of seconds after replacement for which the server
  intends to retain old versions, or null if the server does
  not have a time-based retention policy.  This is a statement
  of server policy, not a guarantee: retention is best effort,
  and the server <bcp14>MAY</bcp14> discard versions sooner (for example, due
  to storage limits).  A version whose <spanx style="verb">replaced</spanx> timestamp is
  more than this many seconds ago has probably been discarded.
  Clients that need to be certain an object remains available
  should not destroy it.</t>
  <t>supportedTypes: "String[]"  <vspace blankLines='1'/>
The names of the data types, from the "JMAP Data Types"
  registry <xref target="IANA-JMAP"/> or private types, for which the server
  supports the history extensions in this account.  A server
  <bcp14>MAY</bcp14> support history for only a subset of the types it
  supports, and <bcp14>MAY</bcp14> retain history for only some objects of
  a supported type (for example, only for some folders).
  Clients <bcp14>MUST</bcp14> ignore type names they do not recognise.</t>
</list></t>

</section>
</section>
<section anchor="extensions-to-fooget"><name>Extensions to Foo/get</name>

<t>When this capability is included in the request's <spanx style="verb">using</spanx> array,
the standard Foo/get method (<xref target="JMAP-CORE"/>, Section 5.1) accepts
the following additional request arguments:</t>

<t><list style="symbols">
  <t>includeReplaced: "Boolean" (default: false)  <vspace blankLines='1'/>
If true, the server returns previous versions of the
  requested objects in addition to the current version.
  Each previous version appears as a separate entry in the
  <spanx style="verb">list</spanx> array, with the same <spanx style="verb">id</spanx> as the current version.
  Every entry includes an <spanx style="verb">objectHistory</spanx> property (see
  below).  Entries with the same <spanx style="verb">id</spanx> <bcp14>MUST</bcp14> be ordered by
  <spanx style="verb">objectHistory.version</spanx> (ascending).  Entries for
  different objects <bcp14>MAY</bcp14> be interleaved.</t>
  <t>includeDestroyed: "Boolean" (default: false)  <vspace blankLines='1'/>
If true, the server also returns objects that have been
  destroyed.  If <spanx style="verb">includeReplaced</spanx> is false, only the final
  version before destruction is returned.  If <spanx style="verb">includeReplaced</spanx>
  is true, all retained historical versions of destroyed
  objects are returned.  For destroyed objects, every entry
  has a non-null <spanx style="verb">objectHistory.replaced</spanx> value, since every
  version has been superseded (the final version was replaced
  by destruction).  <vspace blankLines='1'/>
An object counts as destroyed however it was removed: by
  Foo/set, through another protocol (for example an IMAP EXPUNGE
  <xref target="IMAP"/> or a POP3 DELE <xref target="POP3"/>), or by the server itself, for
  example when it empties a Trash mailbox automatically or destroys
  a Mailbox with <spanx style="verb">onDestroyRemoveEmails</spanx> (<xref target="JMAP-MAIL"/>,
  Section 2.5).  Likewise, changes made through other protocols can
  create versions just as changes made through JMAP do.</t>
  <t>historyAfter: "UTCDate|null" (default: null)  <vspace blankLines='1'/>
If supplied, only versions with an <spanx style="verb">objectHistory.replaced</spanx>
  value strictly after this date are returned, plus the
  current (live) version which has a null <spanx style="verb">replaced</spanx> value.
  If null, no time-based filter is applied.</t>
  <t>historyBefore: "UTCDate|null" (default: null)  <vspace blankLines='1'/>
If supplied, only versions with an <spanx style="verb">objectHistory.replaced</spanx>
  value strictly before this date are returned.  The current
  (live) version, which has a null <spanx style="verb">replaced</spanx> value, is not
  returned.  If null, no time-based filter is applied.  <vspace blankLines='1'/>
A client can use this to page backwards through history: it
  passes the oldest <spanx style="verb">replaced</spanx> value from the previous response
  as <spanx style="verb">historyBefore</spanx> in the next request.  Since <spanx style="verb">historyBefore</spanx>
  applies to every id in the call, a client paging through the
  history of several ids makes a separate Foo/get call for each
  id.  Clients <bcp14>SHOULD</bcp14> pass the <spanx style="verb">replaced</spanx>
  value exactly as received, rather than parsing and
  re-serialising it, since re-serialising at a lower precision
  could cause versions to be skipped.</t>
  <t>historySkip: "UnsignedInt" (default: 0)  <vspace blankLines='1'/>
The number of entries to skip for each id, counting from the
  most recent (the highest version number), before any entries
  are returned.  The current version, if it would otherwise be
  returned, counts as one entry.  For example, a client that
  wants only versions older than the 20 most recent passes
  <spanx style="verb">historySkip: 20</spanx>; any id with 20 or fewer matching entries
  is returned in <spanx style="verb">notFound</spanx>.  <vspace blankLines='1'/>
A client can also use this to page backwards through history,
  by adding the number of entries returned for an id to
  <spanx style="verb">historySkip</spanx> in the next request.  This is less robust than
  <spanx style="verb">historyBefore</spanx>: if a new version is recorded between
  requests, the window shifts and one entry is returned again.</t>
  <t>historyLimit: "UnsignedInt|null" (default: null)  <vspace blankLines='1'/>
If supplied, the maximum number of entries to return in the
  <spanx style="verb">list</spanx> array for each id, including the current version if
  any.  For each id, the server <bcp14>MUST</bcp14> return the most recent
  entries (those with the highest version numbers) remaining
  after <spanx style="verb">historySkip</spanx> is applied, not the oldest.  If null, the
  server returns all remaining retained versions, subject to
  its own limits.</t>
</list></t>

<t>The server applies <spanx style="verb">includeReplaced</spanx>, <spanx style="verb">includeDestroyed</spanx>,
<spanx style="verb">historyAfter</spanx>, and <spanx style="verb">historyBefore</spanx> to select the matching
versions of each id, then skips <spanx style="verb">historySkip</spanx> entries, then
returns at most <spanx style="verb">historyLimit</spanx> of the remaining entries.</t>

<t>If <spanx style="verb">includeReplaced</spanx> and <spanx style="verb">includeDestroyed</spanx> are both false, the
server ignores <spanx style="verb">historyAfter</spanx>, <spanx style="verb">historyBefore</spanx>, <spanx style="verb">historySkip</spanx>, and
<spanx style="verb">historyLimit</spanx>.</t>

<t>If the <spanx style="verb">ids</spanx> argument is null, the server returns all objects of
the type as per <xref target="JMAP-CORE"/>, Section 5.1.  If <spanx style="verb">includeDestroyed</spanx>
is true, this includes every destroyed object for which the server
still retains any version.</t>

<t>The "maxObjectsInGet" limit and the "requestTooLarge" error
(<xref target="JMAP-CORE"/>, Section 5.1) apply to the number of distinct ids,
not to the number of entries in the <spanx style="verb">list</spanx> array.  Each id can
have up to <spanx style="verb">historyLimit</spanx> entries.</t>

<t>If, after applying <spanx style="verb">includeReplaced</spanx>, <spanx style="verb">includeDestroyed</spanx>,
<spanx style="verb">historyAfter</spanx>, <spanx style="verb">historyBefore</spanx>, and <spanx style="verb">historySkip</spanx>, no versions of a
requested id remain to be returned, that id is included in the
<spanx style="verb">notFound</spanx> array.</t>

<section anchor="the-objecthistory-property"><name>The objectHistory property</name>

<t>When <spanx style="verb">includeReplaced</spanx> or <spanx style="verb">includeDestroyed</spanx> is true, each object
in the <spanx style="verb">list</spanx> array includes an additional property:</t>

<t><list style="symbols">
  <t>objectHistory: "ObjectHistoryInfo"  <vspace blankLines='1'/>
An ObjectHistoryInfo object with the following properties:  <list style="symbols">
      <t>version: "UnsignedInt"
A per-object monotonically increasing number that
provides ordering among the versions of a single object
within a response.  Version numbers <bcp14>MAY</bcp14> have gaps (e.g.,
a server may use internal sequence numbers such as modseq
values).  The current (live) version of an object always
has the highest version number.  Servers <bcp14>SHOULD</bcp14> return
consistent version numbers across requests, but clients
<bcp14>MUST NOT</bcp14> rely on this — version numbers exist primarily
to provide ordering within a single response.</t>
      <t>replaced: "UTCDate|null"
The date and time at which this version was superseded,
either by a subsequent update or by destruction.  If null,
this is the current live version of the object.  For
destroyed objects, every version has a non-null <spanx style="verb">replaced</spanx>
value — the final version's <spanx style="verb">replaced</spanx> is the time of
destruction.  The <spanx style="verb">replaced</spanx> values of different versions
of the same object <bcp14>MUST</bcp14> be distinct, so that <spanx style="verb">historyBefore</spanx>
and <spanx style="verb">historyAfter</spanx> partition the history without ambiguity;
a server that records two versions with the same timestamp
can collapse them into a single version.  The value <bcp14>MAY</bcp14>
include fractional seconds (<xref target="JMAP-CORE"/>, Section 1.4),
but servers <bcp14>SHOULD NOT</bcp14> use more than millisecond precision,
as many client date libraries cannot represent more.</t>
      <t>hasOlder: "Boolean"
If true, the server retains at least one older version of
this object than this one, whether or not that version was
returned in this response.  A client can check <spanx style="verb">hasOlder</spanx>
on the oldest entry returned for an id to learn whether
more history is available, and retrieve it using
<spanx style="verb">historyBefore</spanx> or <spanx style="verb">historySkip</spanx>.  The server <bcp14>MAY</bcp14> return
false even if older versions exist (e.g., if it cannot
efficiently determine whether older versions remain).  If
the server returns true, the client <bcp14>MUST NOT</bcp14> assume the
older versions will still be available in a subsequent
request, as the server may purge history at any time.</t>
      <t>expires: "UTCDate|null"
The time after which the server expects to discard this
version, or null if it has no planned time.  The current
(live) version of an object always has a null <spanx style="verb">expires</spanx>.
Like <spanx style="verb">maxHistoryDuration</spanx>, this is a best-effort statement
and not a guarantee: the server <bcp14>MAY</bcp14> discard the version
sooner, for example when storage runs short, and <bcp14>MAY</bcp14> return a
different value in a later response.  A client can use this
to tell the user how long a destroyed object can still be
recovered, but <bcp14>MUST NOT</bcp14> rely on the version remaining
available until then.</t>
    </list></t>
</list></t>

<t>When <spanx style="verb">includeReplaced</spanx> and <spanx style="verb">includeDestroyed</spanx> are both false
(the default), the <spanx style="verb">objectHistory</spanx> property is not included in
the response, and the behaviour is identical to standard Foo/get.</t>

<t>The client <bcp14>MAY</bcp14> include "objectHistory" in the <spanx style="verb">properties</spanx> argument.
It is returned if and only if <spanx style="verb">includeReplaced</spanx> or <spanx style="verb">includeDestroyed</spanx>
is true, regardless of whether it is listed in <spanx style="verb">properties</spanx>.</t>

<t>Which changes produce a version is server dependent: a version is
a snapshot of the object that the server recorded at some point.
The server is not required to create a new version for every
individual change to an object.  For example, rapid successive
updates may be collapsed into a single version, and a server may
choose not to record a version for changes that only affect
server-computed properties.  The server <bcp14>MAY</bcp14> also prune old versions
in any order, so there can be gaps in the version history available
to the client.  Clients <bcp14>MUST NOT</bcp14> assume that the version history is
complete or contiguous.</t>

<t>The values of server-computed properties (for example, the counts
on a Mailbox) in a historical version are also server dependent.
The server <bcp14>SHOULD</bcp14> return the value the property had at the time of
that version if it has that information.</t>

<t>If a historical version contains a reference to a blob (for
example, the <spanx style="verb">blobId</spanx> of an Email), that blob <bcp14>MUST</bcp14> be downloadable
for as long as the server returns that version.  A version that is
not current does not count as a reference to the blob, for garbage
collection (<xref target="JMAP-CORE"/>, Section 6) or for any other purpose, such
as the "blobHasReference" error and Blob/lookup method of
<xref target="JMAP-BLOBEXT"/>.  A server that discards a blob referenced by a
version <bcp14>MUST NOT</bcp14> return that version.</t>

<t>If <spanx style="verb">includeReplaced</spanx> or <spanx style="verb">includeDestroyed</spanx> is true and the data type
is not listed in the <spanx style="verb">supportedTypes</spanx> capability property, the
server <bcp14>MUST</bcp14> reject the call with an "invalidArguments" error.</t>

<t>If the data type is supported but the server does not retain
history for a particular object, it <bcp14>MUST</bcp14> still return the current
version with an <spanx style="verb">objectHistory</spanx> property when requested.  In this
case, the server returns only the current version, with a <spanx style="verb">replaced</spanx>
of null.</t>

</section>
<section anchor="examples"><name>Examples</name>

<section anchor="contact-history"><name>Contact history</name>

<t>Requesting the history of a contact, including all versions:</t>

<figure><sourcecode type="json"><![CDATA[
[["ContactCard/get", {
  "accountId": "abc",
  "ids": ["contact1"],
  "properties": ["name", "emails"],
  "includeReplaced": true,
  "historyLimit": 10
}, "0"]]
]]></sourcecode></figure>

<t>The response includes three versions: the original creation,
a name update, and the current version with an additional email
address:</t>

<figure><sourcecode type="json"><![CDATA[
[["ContactCard/get", {
  "accountId": "abc",
  "state": "abc123",
  "list": [
    {
      "id": "contact1",
      "name": {"full": "Robert Smith"},
      "emails": {
        "e1": {"address": "bob@example.com"}
      },
      "objectHistory": {
        "version": 1,
        "replaced": "2026-02-20T14:15:00Z",
        "hasOlder": false,
        "expires": "2026-03-22T14:15:00Z"
      }
    },
    {
      "id": "contact1",
      "name": {"full": "Bob Smith"},
      "emails": {
        "e1": {"address": "bob@example.com"}
      },
      "objectHistory": {
        "version": 2,
        "replaced": "2026-03-01T09:00:00Z",
        "hasOlder": true,
        "expires": "2026-03-31T09:00:00Z"
      }
    },
    {
      "id": "contact1",
      "name": {"full": "Bob Smith"},
      "emails": {
        "e1": {"address": "bob@example.com"},
        "e2": {"address": "bob@personal.example"}
      },
      "objectHistory": {
        "version": 3,
        "replaced": null,
        "hasOlder": true,
        "expires": null
      }
    }
  ],
  "notFound": []
}, "0"]]
]]></sourcecode></figure>

</section>
<section anchor="recovering-destroyed-emails"><name>Recovering destroyed emails</name>

<t>A client can use Email/changes to discover which emails have been
destroyed, then use a backreference to fetch their final state.
This is useful for displaying a "recently deleted" view:</t>

<figure><sourcecode type="json"><![CDATA[
[
  ["Email/changes", {
    "accountId": "abc",
    "sinceState": "state42"
  }, "0"],
  ["Email/get", {
    "accountId": "abc",
    "#ids": {
      "resultOf": "0",
      "name": "Email/changes",
      "path": "/destroyed"
    },
    "properties": ["subject", "from", "receivedAt"],
    "includeDestroyed": true
  }, "1"]
]
]]></sourcecode></figure>

<t>The Email/get response returns the final state of each
destroyed email.  The <spanx style="verb">objectHistory.replaced</spanx> value is the
time of destruction:</t>

<figure><sourcecode type="json"><![CDATA[
[["Email/get", {
  "accountId": "abc",
  "state": "state43",
  "list": [
    {
      "id": "email42",
      "subject": "Meeting notes",
      "from": [{"name": "Alice",
        "email": "alice@example.com"}],
      "receivedAt": "2026-03-10T09:00:00Z",
      "objectHistory": {
        "version": 1,
        "replaced": "2026-03-15T16:30:00Z",
        "hasOlder": false,
        "expires": "2026-04-14T16:30:00Z"
      }
    },
    {
      "id": "email57",
      "subject": "Project update",
      "from": [{"name": "Bob",
        "email": "bob@example.com"}],
      "receivedAt": "2026-03-12T14:00:00Z",
      "objectHistory": {
        "version": 1,
        "replaced": "2026-03-15T16:31:00Z",
        "hasOlder": false,
        "expires": "2026-04-14T16:31:00Z"
      }
    }
  ],
  "notFound": []
}, "1"]]
]]></sourcecode></figure>

<t>Since <spanx style="verb">includeReplaced</spanx> was not set, only the final version of
each destroyed email is returned.  The non-null <spanx style="verb">replaced</spanx>
value indicates when each email was destroyed.  The server in
this example keeps history for 30 days.</t>

</section>
</section>
</section>
<section anchor="query"><name>Extensions to Foo/query</name>

<t>The Foo/changes approach in <xref target="recovering-destroyed-emails"/> only
works for a client that holds a state string from before the
objects were destroyed, and only while the server can still
calculate changes from that state.  Foo/get with a null <spanx style="verb">ids</spanx>
argument and <spanx style="verb">includeDestroyed</spanx> returns every retained object of
the type at once, with no filtering, sorting or paging.</t>

<t>When this capability is included in the request's <spanx style="verb">using</spanx> array,
the standard Foo/query method (<xref target="JMAP-CORE"/>, Section 5.5) accepts
the following additional request arguments:</t>

<t><list style="symbols">
  <t>onlyDestroyed: "Boolean" (default: false)  <vspace blankLines='1'/>
If true, the query runs over the destroyed objects of this
  type for which the server still retains at least one version,
  instead of over current objects.  An object that has been
  restored (<xref target="restoring"/>) is a current object again, and is not
  included.</t>
  <t>destroyedAfter: "UTCDate|null" (default: null)  <vspace blankLines='1'/>
If supplied, only objects destroyed strictly after this date
  are included.</t>
  <t>destroyedBefore: "UTCDate|null" (default: null)  <vspace blankLines='1'/>
If supplied, only objects destroyed strictly before this date
  are included.</t>
</list></t>

<t>The time an object was destroyed is the <spanx style="verb">replaced</spanx> value of its
final version.</t>

<t>The server <bcp14>MUST</bcp14> reject the call with an "invalidArguments" error if
<spanx style="verb">onlyDestroyed</spanx> is true and the type is not listed in
<spanx style="verb">supportedTypes</spanx>, or if <spanx style="verb">destroyedAfter</spanx> or <spanx style="verb">destroyedBefore</spanx> is
supplied and <spanx style="verb">onlyDestroyed</spanx> is false.</t>

<t>When <spanx style="verb">onlyDestroyed</spanx> is true:</t>

<t><list style="symbols">
  <t>The <spanx style="verb">filter</spanx> and <spanx style="verb">sort</spanx> arguments apply to the final version of
each destroyed object.  The server need not support every filter
condition or comparator for destroyed objects that it supports
for current objects.  It rejects one it does not support with
"unsupportedFilter" or "unsupportedSort", as usual.</t>
  <t>If <spanx style="verb">sort</spanx> is null or empty, the results are ordered by time of
destruction, most recent first.</t>
  <t>Arguments that apply only to current objects, such as
<spanx style="verb">collapseThreads</spanx> for Email, are ignored.</t>
  <t>Foo/queryChanges works as for any other query.  An object leaves
the results when it is restored or discarded, and enters them
when it is destroyed.  A server that cannot track these changes
<bcp14>MAY</bcp14> return a "cannotCalculateChanges" error.</t>
</list></t>

<t>The ids returned can then be passed to Foo/get with
<spanx style="verb">includeDestroyed</spanx> set, usually with a backreference.</t>

<section anchor="example"><name>Example</name>

<t>A client builds a "recently deleted" view of the 50 emails
destroyed most recently since 1 March:</t>

<figure><sourcecode type="json"><![CDATA[
[
  ["Email/query", {
    "accountId": "abc",
    "onlyDestroyed": true,
    "destroyedAfter": "2026-03-01T00:00:00Z",
    "limit": 50
  }, "0"],
  ["Email/get", {
    "accountId": "abc",
    "#ids": {
      "resultOf": "0",
      "name": "Email/query",
      "path": "/ids"
    },
    "properties": ["subject", "from", "receivedAt"],
    "includeDestroyed": true
  }, "1"]
]
]]></sourcecode></figure>

<t>The Email/query response lists the destroyed emails, most recently
destroyed first:</t>

<figure><sourcecode type="json"><![CDATA[
[["Email/query", {
  "accountId": "abc",
  "queryState": "dq7",
  "canCalculateChanges": true,
  "position": 0,
  "ids": ["email57", "email42"]
}, "0"]]
]]></sourcecode></figure>

<t>The Email/get response is the same as in
<xref target="recovering-destroyed-emails"/>.</t>

</section>
</section>
<section anchor="restoring"><name>Restoring Objects</name>

<t>To restore an earlier version of an existing object, the client
uses a normal Foo/set update with the values from that version.</t>

<t>To restore a destroyed object, the client uses the <spanx style="verb">restore</spanx>
argument of Foo/set.</t>

<section anchor="extensions-to-fooset"><name>Extensions to Foo/set</name>

<t>When this capability is included in the request's <spanx style="verb">using</spanx> array,
the standard Foo/set method (<xref target="JMAP-CORE"/>, Section 5.3) accepts
the following additional request argument:</t>

<t><list style="symbols">
  <t>restore: "Id[PatchObject|null]|null" (default: null)  <vspace blankLines='1'/>
A map of the ids of destroyed objects to restore.  Each value
  is null, or a PatchObject to apply to the restored object.  An
  empty PatchObject means the same as null.</t>
</list></t>

<t>The response has the following additional properties:</t>

<t><list style="symbols">
  <t>restored: "Id[Foo|null]|null"  <vspace blankLines='1'/>
A map of the ids of objects that were successfully restored.
  The value for each is an object containing any properties of the
  restored object whose values differ from those in the final
  version with the patch applied, or null if there are none.  This
  is null if no objects were restored.</t>
  <t>notRestored: "Id[SetError]|null"  <vspace blankLines='1'/>
A map of the ids of objects that could not be restored to a
  SetError object explaining why.  This is null if every restore
  succeeded or none was requested.</t>
</list></t>

<t>The server <bcp14>MUST</bcp14> reject the call with an "invalidArguments" error if
<spanx style="verb">restore</spanx> is non-null and the type is not listed in
<spanx style="verb">supportedTypes</spanx>.</t>

<t>The server processes each restore before any create, update, or
destroy in the same call, so these can refer to a restored object.
The restored object takes the id of the destroyed object, and the
values of the final version of that object
(<xref target="the-objecthistory-property"/>), with the PatchObject applied.  The
patch follows the same rules as a PatchObject in an update in
Foo/set.  This includes server-set properties, such as the
<spanx style="verb">threadId</spanx> and <spanx style="verb">size</spanx> of an Email.  These keep their values from
the final version, unless the server cannot keep them, for
example if the Thread no longer exists; the server then sets new
values and returns them in <spanx style="verb">restored</spanx>.</t>

<t>The history of the restored object continues from that of the
destroyed object, so the destroyed versions become previous versions
of the restored object.  To restore a version other than the final
one, the client includes the values of that version in the
PatchObject.</t>

<t>The server rejects a restore with a SetError as follows:</t>

<t><list style="symbols">
  <t>notFound: The id is not the id of a destroyed object of this type
for which the server retains any history.  This includes the id of
a current object.</t>
  <t>invalidPatch: The PatchObject is not valid.</t>
  <t>invalidProperties: The restored object would not be valid, as for
an update in Foo/set.</t>
  <t>forbidden: The server does not allow this object to be restored,
for example because of its content (<xref target="harmful-content"/>).</t>
  <t>overQuota: The restored object would exceed a quota.</t>
</list></t>

<t>The server <bcp14>MAY</bcp14> also return any other SetError that Foo/set returns
for an update or create of this type.</t>

<t>The server <bcp14>MUST NOT</bcp14> reuse the id of a destroyed object for which it
retains any history, other than by restoring that object.</t>

<t>Foo/changes reports a restored id in <spanx style="verb">updated</spanx> if the object existed
at <spanx style="verb">sinceState</spanx>, and in <spanx style="verb">created</spanx> otherwise.  It never reports a
restored id in <spanx style="verb">destroyed</spanx>.</t>

</section>
<section anchor="type-specific-notes"><name>Type-Specific Notes</name>

<t>A restored Email is the original message: it has the same <spanx style="verb">blobId</spanx>,
and so the same content, as the final version.  A client can
restore an Email with Email/set without fetching its content first.</t>

<t>A SieveScript <xref target="JMAP-SIEVE"/> is deactivated before it is destroyed
(<xref target="JMAP-SIEVE"/>, Section 2.4), so a restored SieveScript is not
active.  The client can activate it with <spanx style="verb">onSuccessActivateScript</spanx>,
using its id.</t>

<t>The final version may refer to an object that no longer exists,
such as a Mailbox in an Email's <spanx style="verb">mailboxIds</spanx>.  The server then
rejects the restore as it would an update that refers to a
nonexistent object.  The client can restore that object first, in
the same call or an earlier one, since Mailbox, AddressBook, and
Calendar can have history too.  Or it can choose another one in the
PatchObject, for example the Mailbox with the "inbox" role.  The
server can also reject a restore that conflicts with a current
object, using the error that Foo/set would normally return; for
example, a SieveScript whose name is now used by another script is
rejected with "alreadyExists" (<xref target="JMAP-SIEVE"/>, Section 2.4).</t>

</section>
<section anchor="example-1"><name>Example</name>

<t>Having found email42 with Email/query (see <xref target="query"/>), the client
restores it.  The Mailbox it was in has since been destroyed, so
the client puts it in the Inbox (mb1):</t>

<figure><sourcecode type="json"><![CDATA[
[["Email/set", {
  "accountId": "abc",
  "restore": {
    "email42": {
      "mailboxIds": {"mb1": true}
    }
  }
}, "0"]]
]]></sourcecode></figure>

<t>The server restores the Email.  It has kept its <spanx style="verb">threadId</spanx>, so no
properties are returned:</t>

<figure><sourcecode type="json"><![CDATA[
[["Email/set", {
  "accountId": "abc",
  "oldState": "s110",
  "newState": "s111",
  "created": null,
  "updated": null,
  "destroyed": null,
  "notCreated": null,
  "notUpdated": null,
  "notDestroyed": null,
  "restored": {"email42": null},
  "notRestored": null
}, "0"]]
]]></sourcecode></figure>

</section>
</section>
<section anchor="design-rationale"><name>Design Rationale</name>

<t>This section is not normative.</t>

<t>History is returned through the existing Foo/get method rather than
a new method.  The entries in the <spanx style="verb">list</spanx> array are ordinary objects
of the data type, so a client can feed them to the same parser it
uses for current objects, and the existing <spanx style="verb">properties</spanx> argument
works unchanged.  It also allows a client to fetch the final state
of many destroyed objects in a single call, using a backreference
to the <spanx style="verb">destroyed</spanx> list from Foo/changes, as shown in the examples
above.</t>

<t>The history metadata is embedded in each object as the
<spanx style="verb">objectHistory</spanx> property, rather than wrapping each object in a
separate container, for the same reason: the entries remain
ordinary objects.  This follows the existing pattern of JMAP-specific
properties such as <spanx style="verb">id</spanx> being added to objects whose format is
defined elsewhere; the <spanx style="verb">objectHistory</spanx> name is reserved in the
relevant property registries (see <xref target="iana-considerations"/>).</t>

<t>Each entry is a full copy of the object rather than a patch
against the previous version.  Patches would save space, but the
client would need every intermediate version to reconstruct any
one of them, which conflicts with the server's freedom to prune
versions, and the final version of a destroyed object would need
to be returned in full anyway.</t>

<t>Every superseded version carries a <spanx style="verb">replaced</spanx> timestamp.  The
server always knows, at least approximately, when it replaced a
snapshot it was keeping, and the timestamp is what a client needs
to present history to a user and to filter it with <spanx style="verb">historyAfter</spanx>.</t>

<t>Destroyed objects are restored with a new <spanx style="verb">restore</spanx> argument to
Foo/set rather than by creating an object with the old id.  A
create in Foo/set cannot set the id or server-set properties, so the
restored object would differ from the original; an Email created
with Email/set is a new message, not the original one.  Restoring
the final version, with a patch, brings back the object exactly,
and the client need not send the whole object back to the server.</t>

<t>Destroyed objects are found with Foo/query rather than a new
method, for the same reasons: the ids it returns go straight into
Foo/get with <spanx style="verb">includeDestroyed</spanx>.  The query runs over destroyed
objects only, rather than over current and destroyed objects
together, because "recently deleted" is normally a separate view.
It also lets a server keep destroyed objects in a separate index.</t>

</section>
<section anchor="iana-considerations"><name>IANA Considerations</name>

<section anchor="jmap-capability-registration-for-urnietfparamsjmapobject-history"><name>JMAP Capability Registration for urn:ietf:params:jmap:object-history</name>

<t>IANA is requested to register the "Object History" Capability
as follows:</t>

<t>Capability Name: urn:ietf:params:jmap:object-history</t>

<t>Intended use: common</t>

<t>Change Controller: IETF</t>

<t>Specification document: this document</t>

<t>Security and privacy considerations: this document,
Security Considerations</t>

</section>
<section anchor="update-to-the-jmap-data-types-registry"><name>Update to the JMAP Data Types Registry</name>

<t>This document adds a "Supports History" column to the "JMAP Data
Types" registry <xref target="IANA-JMAP"/>.  The value
is "Yes" or "No", indicating whether the data type supports the
history extensions defined in this document.</t>

<t>The initial values for existing registrations are:</t>

<texttable>
      <ttcol align='left'>Type Name</ttcol>
      <ttcol align='left'>Supports History</ttcol>
      <c>Core</c>
      <c>No</c>
      <c>PushSubscription</c>
      <c>No</c>
      <c>Mailbox</c>
      <c>Yes</c>
      <c>Thread</c>
      <c>No</c>
      <c>Email</c>
      <c>Yes</c>
      <c>EmailDelivery</c>
      <c>No</c>
      <c>SearchSnippet</c>
      <c>No</c>
      <c>Identity</c>
      <c>Yes</c>
      <c>EmailSubmission</c>
      <c>No</c>
      <c>VacationResponse</c>
      <c>Yes</c>
      <c>MDN</c>
      <c>No</c>
      <c>Quota</c>
      <c>No</c>
      <c>SieveScript</c>
      <c>Yes</c>
      <c>Principal</c>
      <c>No</c>
      <c>ShareNotification</c>
      <c>No</c>
      <c>AddressBook</c>
      <c>Yes</c>
      <c>ContactCard</c>
      <c>Yes</c>
      <c>Calendar</c>
      <c>Yes</c>
      <c>CalendarEvent</c>
      <c>Yes</c>
      <c>CalendarEventNotification</c>
      <c>No</c>
      <c>ParticipantIdentity</c>
      <c>Yes</c>
      <c>FileNode</c>
      <c>Yes</c>
</texttable>

<t>FileNode is registered by <xref target="JMAP-FILENODE"/>.</t>

<t>The default value for this column is "No".  New registrations
that do not explicitly include a value are assumed not to
support history.</t>

<t>This column records whether history is meaningful for a data type.
Whether a particular server supports history for a type is
advertised in the <spanx style="verb">supportedTypes</spanx> capability property.</t>

</section>
<section anchor="jscontact-property-registration"><name>JSContact Property Registration</name>

<t>IANA is requested to register the following property in the
"JSContact Properties" registry defined in <xref target="JSCONTACT"/>,
Section 3, so that the name cannot be used for a property of a
JSContact Card.</t>

<t>Property Name:  objectHistory</t>

<t>Property Type:  not applicable</t>

<t>Property Context:  Card</t>

<t>Intended Usage:  reserved</t>

<t>Since Version:  1.0</t>

<t>Change Controller:  IETF</t>

<t>Reference:  this document</t>

</section>
<section anchor="jscalendar-property-registration"><name>JSCalendar Property Registration</name>

<t>IANA is requested to register the following property in the
"JSCalendar Properties" registry defined in <xref target="JSCALENDAR"/>,
Section 8.2, so that the name cannot be used for a property of a
JSCalendar object.</t>

<t>Property Name:  objectHistory</t>

<t>Property Type:  not applicable</t>

<t>Property Context:  Event, Task, Group</t>

<t>Intended Usage:  reserved</t>

<t>Change Controller:  IETF</t>

<t>Reference:  this document</t>

<t>Specifications that define a JMAP data type whose object format is
also governed by a separate property registry <bcp14>SHOULD</bcp14> reserve the
<spanx style="verb">objectHistory</spanx> property name in that registry.</t>

</section>
</section>
<section anchor="security-considerations"><name>Security Considerations</name>

<t>All security considerations from <xref target="JMAP-CORE"/> apply to this
document.</t>

<section anchor="storage-and-resource-consumption"><name>Storage and Resource Consumption</name>

<t>Retaining historical versions of objects can consume significant
server storage.  Servers <bcp14>SHOULD</bcp14> impose reasonable limits on
history retention, either by duration (advertised via
<spanx style="verb">maxHistoryDuration</spanx>) or by total storage.  Servers <bcp14>MAY</bcp14>
silently discard history entries when storage limits are
reached.</t>

<t>Counting retained history towards a user's quota (<xref target="JMAP-QUOTAS"/>)
is <bcp14>NOT RECOMMENDED</bcp14>.  If it counts, a user who destroys objects to
free space sees no change until the history expires.  A restored
object counts towards quota as any newly created object does.</t>

</section>
<section anchor="access-control"><name>Access Control</name>

<t>Historical versions of an object <bcp14>MUST</bcp14> respect the same access
controls as the current version.  A user who does not have
permission to read an object <bcp14>MUST NOT</bcp14> be able to read its
history.</t>

<t>Access rights can change over time, for example when an object is
shared with a new user, or moved into a shared container.  The
server <bcp14>MUST NOT</bcp14> return a historical version to a user who could not
have read that version at the time it was current.  This requires
the server to track changes to access rights.  A server that does
not keep a full history of access rights can take a conservative
approach: record the point at which the access rights affecting an
object (or its containing object, such as a Mailbox or AddressBook)
last changed, for example as a modseq, and not return any version
that was replaced before that point.</t>

<t>Similarly, for destroyed objects, the server <bcp14>MUST NOT</bcp14> reveal the
existence or content of a destroyed object to a user who could not
read it at the time it was destroyed.</t>

</section>
<section anchor="information-disclosure"><name>Information Disclosure</name>

<t>Object history may reveal information that the user or an
administrator intended to remove.  For example, a contact
record that was updated to remove a phone number will still
have that phone number visible in its history.  Servers
<bcp14>SHOULD</bcp14> provide administrators with the ability to purge
history for specific objects when required for privacy or
compliance reasons.</t>

</section>
<section anchor="privacy-considerations"><name>Privacy Considerations</name>

<t>When a server supports this extension, updating or destroying an
object does not immediately remove the previous content from the
server; it remains retrievable by anyone with read access to the
object until the server discards it under its retention policy.
Users may not expect this.  This is not new in kind (servers
commonly retain deleted data in backups, and many mail systems
offer a "recently deleted" view), but this extension makes such
data retrievable through the protocol.</t>

<t>Servers <bcp14>SHOULD</bcp14> make their retention policy visible to users, for
example through the <spanx style="verb">maxHistoryDuration</spanx> capability property and
the server's user interface.  Clients that present a "destroy"
operation to users <bcp14>SHOULD NOT</bcp14> describe it as irreversible or
permanent when the server advertises this capability for that data
type.  Whether, and how, a user can request that history be purged
before the end of the retention period is a matter of server
policy and is outside the scope of this document.</t>

</section>
<section anchor="harmful-content"><name>Harmful Content</name>

<t>An administrator may remove content from an account because it is
harmful, for example a phishing message or malware.  The server <bcp14>MAY</bcp14>
decline to retain history for such an object, and <bcp14>MAY</bcp14> reject an
attempt to restore it with a "forbidden" SetError, so that the user
cannot bring the content back.</t>

</section>
</section>
<section anchor="changes"><name>Changes</name>

<t>EDITOR: please remove this section before publication.</t>

<t>The source of this document exists on github at: https://github.com/brong/draft-gondwana-jmap-object-history/</t>

<t><strong>draft-ietf-jmap-object-history-03</strong></t>

<t><list style="symbols">
  <t>Added John Coffey as co-author; folded in material from
draft-coffey-jmap-undelete.</t>
  <t>Added Foo/query arguments <spanx style="verb">onlyDestroyed</spanx>, <spanx style="verb">destroyedAfter</spanx>, and
<spanx style="verb">destroyedBefore</spanx>, for finding destroyed objects without an old
state string.</t>
  <t>Replaced restoring by creating with the old id (and Email/import
with the old id) with a new Foo/set <spanx style="verb">restore</spanx> argument, which
restores the final version with an optional patch, keeping
server-set properties.  Notes on Email, SieveScript, missing
containers, and conflicts.</t>
  <t>Added a per-version <spanx style="verb">expires</spanx> to <spanx style="verb">objectHistory</spanx>.</t>
  <t>Destruction through other protocols and by the server counts as
destruction.</t>
  <t>Security: quota, harmful content.</t>
  <t>Paging several ids with <spanx style="verb">historyBefore</spanx> takes one Foo/get call per
id.</t>
  <t>The history arguments are ignored unless <spanx style="verb">includeReplaced</spanx> or
<spanx style="verb">includeDestroyed</spanx> is true.</t>
  <t>Foo/changes reports a restored id as updated or created, never as
destroyed.</t>
  <t>Versions that are not current do not count as blob references.</t>
  <t>Added FileNode to the "Supports History" table.</t>
  <t>Thanks to Mark Atwood for an implementation review.</t>
</list></t>

<t><strong>draft-ietf-jmap-object-history-02</strong></t>

<t><list style="symbols">
  <t>Replaced the top-level <spanx style="verb">hasMoreHistory</spanx> response property with a
per-entry <spanx style="verb">objectHistory.hasOlder</spanx> property, so the client can
tell which ids have more history.</t>
  <t>Added <spanx style="verb">historySkip</spanx>, to skip the N most recent versions of each
id; ids with N or fewer versions are returned in <spanx style="verb">notFound</spanx>.</t>
</list></t>

<t><strong>draft-ietf-jmap-object-history-01</strong></t>

<t><list style="symbols">
  <t>Removed "Updates: 8620"; the JMAP Data Types registry is not
defined by RFC 8620.  The registry is now referenced by name
rather than by its defining document.</t>
  <t>Corrected the registry table to match the current registry.</t>
  <t><spanx style="verb">historyLimit</spanx> is now per id.</t>
  <t>Defined behaviour for <spanx style="verb">ids: null</spanx> with <spanx style="verb">includeDestroyed</spanx>, and
clarified that "maxObjectsInGet" counts ids, not entries.</t>
  <t>Ids with no matching versions are returned in <spanx style="verb">notFound</spanx>.</t>
  <t>Which changes create a version, and the values of server-computed
properties, are server dependent.</t>
  <t>Blobs referenced by returned versions must be downloadable.</t>
  <t>Expanded access control considerations for changing access rights.</t>
  <t>Added <spanx style="verb">supportedTypes</spanx> to the account capability; requesting
history for an unsupported type is an error.</t>
  <t>Reserved the <spanx style="verb">objectHistory</spanx> property name in the JSContact and
JSCalendar property registries.</t>
  <t>Added acknowledgements.</t>
  <t>Added a Design Rationale section (Foo/get rather than a new method,
embedded metadata, full objects rather than patches, timestamps).</t>
  <t>Added a Restoring Objects section: a client may ask to recreate a
destroyed object with its old id, and the server may accept or
reject; ids of destroyed objects are otherwise not reused.</t>
  <t><spanx style="verb">maxHistoryDuration</spanx> is now a best-effort statement of server policy.</t>
  <t>Clarified that "objectHistory" may appear in <spanx style="verb">properties</spanx>.</t>
  <t>Added Privacy Considerations.</t>
  <t>Added <spanx style="verb">historyBefore</spanx> for paging backwards through history;
versions of the same object have distinct <spanx style="verb">replaced</spanx> values, with
at most millisecond precision.</t>
  <t>Removed the audit use case from the introduction.</t>
</list></t>

<t><strong>draft-ietf-jmap-object-history-00</strong></t>

<t><list style="symbols">
  <t>Uploaded with working-group adopted name.</t>
</list></t>

<t><strong>draft-gondwana-jmap-object-history-00</strong></t>

<t><list style="symbols">
  <t>initial proposal</t>
</list></t>

</section>
<section anchor="acknowledgements"><name>Acknowledgements</name>

<t>The authors would like to thank Mark Atwood, Ben Bucksch, Mauro De
Gennaro, Arnt Gulbrandsen, Neil Jenkins, and Robert Stepanek for their
feedback on this document.</t>

</section>


  </middle>

  <back>


<references title='References' anchor="sec-combined-references">

    <references title='Normative References' anchor="sec-normative-references">



<reference anchor="JMAP-CORE">
  <front>
    <title>The JSON Meta Application Protocol (JMAP)</title>
    <author fullname="N. Jenkins" initials="N." surname="Jenkins"/>
    <author fullname="C. Newman" initials="C." surname="Newman"/>
    <date month="July" year="2019"/>
    <abstract>
      <t>This document specifies a protocol for clients to efficiently query, fetch, and modify JSON-based data objects, with support for push notification of changes and fast resynchronisation and for out-of- band binary data upload/download.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="8620"/>
  <seriesInfo name="DOI" value="10.17487/RFC8620"/>
</reference>

<reference anchor="RFC2119">
  <front>
    <title>Key words for use in RFCs to Indicate Requirement Levels</title>
    <author fullname="S. Bradner" initials="S." surname="Bradner"/>
    <date month="March" year="1997"/>
    <abstract>
      <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="2119"/>
  <seriesInfo name="DOI" value="10.17487/RFC2119"/>
</reference>

<reference anchor="RFC8174">
  <front>
    <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
    <author fullname="B. Leiba" initials="B." surname="Leiba"/>
    <date month="May" year="2017"/>
    <abstract>
      <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="14"/>
  <seriesInfo name="RFC" value="8174"/>
  <seriesInfo name="DOI" value="10.17487/RFC8174"/>
</reference>




    </references>

    <references title='Informative References' anchor="sec-informative-references">



<reference anchor="JMAP-MAIL">
  <front>
    <title>The JSON Meta Application Protocol (JMAP) for Mail</title>
    <author fullname="N. Jenkins" initials="N." surname="Jenkins"/>
    <author fullname="C. Newman" initials="C." surname="Newman"/>
    <date month="August" year="2019"/>
    <abstract>
      <t>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.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="8621"/>
  <seriesInfo name="DOI" value="10.17487/RFC8621"/>
</reference>

<reference anchor="JMAP-CONTACTS">
  <front>
    <title>JSON Meta Application Protocol (JMAP) for Contacts</title>
    <author fullname="N. Jenkins" initials="N." role="editor" surname="Jenkins"/>
    <date month="December" year="2024"/>
    <abstract>
      <t>This document specifies a data model for synchronising contact data with a server using the JSON Meta Application Protocol (JMAP).</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9610"/>
  <seriesInfo name="DOI" value="10.17487/RFC9610"/>
</reference>


<reference anchor="JMAP-BLOBEXT">
   <front>
      <title>JMAP Blob Management</title>
      <author fullname="Bron Gondwana" initials="B." surname="Gondwana">
         <organization>Fastmail</organization>
      </author>
      <date day="2" month="November" year="2026"/>
      <abstract>
	 <t>   The JSON Meta Application Protocol (JMAP) base protocol ([JMAP-CORE])
   provides the ability to upload and download arbitrary binary data via
   HTTP POST and GET on a defined endpoint.  This binary data is called
   a &quot;blob&quot;.

   This extension adds additional ways to create and access blobs by
   making inline method calls within a standard JMAP request.  It also
   adds a reverse lookup mechanism to discover where blobs are
   referenced within other data types, support for large blobs via
   chunked construction with server-side optimisation, and server-side
   blob conversion operations including image format conversion, archive
   creation and extraction, compression and decompression, and delta/
   patch operations.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-ietf-jmap-blobext-03"/>
   
</reference>


<reference anchor="JMAP-FILENODE">
   <front>
      <title>JMAP File Storage extension</title>
      <author fullname="Bron Gondwana" initials="B." surname="Gondwana">
         <organization>Fastmail</organization>
      </author>
      <date day="2" month="November" year="2026"/>
      <abstract>
	 <t>   The JMAP base protocol (RFC 8620) provides the ability to upload and
   download arbitrary binary data.  This binary data is called a &quot;blob&quot;,
   and can be used in all other JMAP extensions.

   This extension adds a FileNode data type and methods to expose blobs
   as a filesystem, along with the types of metadata that are provided
   by other remote filesystem protocols.

	 </t>
      </abstract>
   </front>
   <seriesInfo name="Internet-Draft" value="draft-ietf-jmap-filenode-20"/>
   
</reference>

<reference anchor="JMAP-QUOTAS">
  <front>
    <title>JSON Meta Application Protocol (JMAP) for Quotas</title>
    <author fullname="R. Cordier" initials="R." role="editor" surname="Cordier"/>
    <date month="June" year="2023"/>
    <abstract>
      <t>This document specifies a data model for handling quotas on accounts with a server using the JSON Meta Application Protocol (JMAP).</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9425"/>
  <seriesInfo name="DOI" value="10.17487/RFC9425"/>
</reference>

<reference anchor="JMAP-SIEVE">
  <front>
    <title>The JSON Meta Application Protocol (JMAP) for Sieve Scripts</title>
    <author fullname="K. Murchison" initials="K." surname="Murchison"/>
    <date month="September" year="2024"/>
    <abstract>
      <t>This document specifies a data model for managing Sieve scripts on a server using the JSON Meta Application Protocol (JMAP). Clients can use this protocol to efficiently search, access, organize, and validate Sieve scripts.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9661"/>
  <seriesInfo name="DOI" value="10.17487/RFC9661"/>
</reference>

<reference anchor="IMAP">
  <front>
    <title>Internet Message Access Protocol (IMAP) - Version 4rev2</title>
    <author fullname="A. Melnikov" initials="A." role="editor" surname="Melnikov"/>
    <author fullname="B. Leiba" initials="B." role="editor" surname="Leiba"/>
    <date month="August" year="2021"/>
    <abstract>
      <t>The Internet Message Access Protocol Version 4rev2 (IMAP4rev2) allows a client to access and manipulate electronic mail messages on a server. IMAP4rev2 permits manipulation of mailboxes (remote message folders) in a way that is functionally equivalent to local folders. IMAP4rev2 also provides the capability for an offline client to resynchronize with the server.</t>
      <t>IMAP4rev2 includes operations for creating, deleting, and renaming mailboxes; checking for new messages; removing messages permanently; setting and clearing flags; parsing per RFCs 5322, 2045, and 2231; searching; and selective fetching of message attributes, texts, and portions thereof. Messages in IMAP4rev2 are accessed by the use of numbers. These numbers are either message sequence numbers or unique identifiers.</t>
      <t>IMAP4rev2 does not specify a means of posting mail; this function is handled by a mail submission protocol such as the one specified in RFC 6409.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9051"/>
  <seriesInfo name="DOI" value="10.17487/RFC9051"/>
</reference>

<reference anchor="POP3">
  <front>
    <title>Post Office Protocol - Version 3</title>
    <author fullname="J. Myers" initials="J." surname="Myers"/>
    <author fullname="M. Rose" initials="M." surname="Rose"/>
    <date month="May" year="1996"/>
    <abstract>
      <t>The Post Office Protocol - Version 3 (POP3) is intended to permit a workstation to dynamically access a maildrop on a server host in a useful fashion. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="STD" value="53"/>
  <seriesInfo name="RFC" value="1939"/>
  <seriesInfo name="DOI" value="10.17487/RFC1939"/>
</reference>

<reference anchor="JSCONTACT">
  <front>
    <title>JSContact: A JSON Representation of Contact Data</title>
    <author fullname="R. Stepanek" initials="R." surname="Stepanek"/>
    <author fullname="M. Loffredo" initials="M." surname="Loffredo"/>
    <date month="May" year="2024"/>
    <abstract>
      <t>This specification defines a data model and JavaScript Object Notation (JSON) representation of contact card information that can be used for data storage and exchange in address book or directory applications. It aims to be an alternative to the vCard data format and to be unambiguous, extendable, and simple to process. In contrast to the JSON-based jCard format, it is not a direct mapping from the vCard data model and expands semantics where appropriate. Two additional specifications define new vCard elements and how to convert between JSContact and vCard.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="9553"/>
  <seriesInfo name="DOI" value="10.17487/RFC9553"/>
</reference>

<reference anchor="JSCALENDAR">
  <front>
    <title>JSCalendar: A JSON Representation of Calendar Data</title>
    <author fullname="N. Jenkins" initials="N." surname="Jenkins"/>
    <author fullname="R. Stepanek" initials="R." surname="Stepanek"/>
    <date month="July" year="2021"/>
    <abstract>
      <t>This specification defines a data model and JSON representation of calendar data that can be used for storage and data exchange in a calendaring and scheduling environment. It aims to be an alternative and, over time, successor to the widely deployed iCalendar data format. It also aims to be unambiguous, extendable, and simple to process. In contrast to the jCal format, which is also based on JSON, JSCalendar is not a direct mapping from iCalendar but defines the data model independently and expands semantics where appropriate.</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="8984"/>
  <seriesInfo name="DOI" value="10.17487/RFC8984"/>
</reference>


<reference anchor="IANA-JMAP" target="https://www.iana.org/assignments/jmap/">
  <front>
    <title>JSON Meta Application Protocol (JMAP)</title>
    <author >
      <organization>IANA</organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>


    </references>

</references>



  </back>

<!-- ##markdown-source:
H4sIAAAAAAAAA81923bcxrXgO76ipv0QUatJkZTkY7fOOieURNn00i0klTkZ
x2uIblSzYaKBDgpNikdW1nzEfMB8y3zKfMnsa13QaIp2ksn4IaHQqELVvt9q
1+7ubtaVXWUn5oc3R+/Nu+nPdtaZ70vXNe1tlk+nrb0e/q1oZnW+hIFFm8+7
3dJ2892fl/lqt6H3dhf83u7+48ytp8vSubKpz29XMOLk+PxVNss7ewkvTIzr
iqyZuqaynXWTrFy1E9O1a9cd7u9/u3+YXdnbm6YtYFzd2ba23e5L/GTmurwu
/nteNTXMeWtdtion5seumY2Na9qutXMHf90u8Y+fsixfd4umnWRmNzPwX1m7
iXm+Z75r6uImr3N6yDt63jZ1+rxpLyfmVe66ZV5W9MTiXxMzhVcvfz+XXzqb
L/dmzTL5xg975kUzn9vb6As/NIs6fkrz87/N63zq4k/8DO/+fka/VfDTHryb
ZXXTLvOuvLYTehURtPvi3enxxJy+evHN14f7WVbW84GX3hydvNaXDuKxb8+P
Xpyf0U/ffn2wH356/vrd8+P/OAfw777cC2ieVs3UfuzCe69OXh+/fffyuP/i
vKxs3RQ2vPmHD+/Oj+RTTw6fhh/OTo7/eCxL+JpXdwLP+cn+U37y/t37x/Tk
4NvH3/LYM1k+v/j06WN9fARLenl0yhv+9psnPOXR26Nd/B6DBf/r8vbSdhOz
6LqVmzx6dHNzs1cC8hHYj3Ig3ct6aevOPcIdPQrDhHXO3r01b2yXm6PVqiqB
soHUzfu2AVpsKvMAv7XjB3k61P92w59KCrjELNvd3TWA8a7NZ12WnS8sM+I0
d9as/OyC8B18dF0W1pmlhS8UzgD+gf7r2QKItPzPsr7MOphjtm5b2AuwHXCg
aeamyGHlzLXOTG13Y21tZlWJLwGHGWfba9vuGXMOPJ0Bzm2NvGzyAr6BM+bT
siq7W9M1prVdW9pra5j9ARaVgcH4vsNvyWfGQJ2zal3AmvyXu0XemUUOY6e4
ANhI1za3thib6a2hr9Lr+EHi/LwtsldN8wgQJzse4wrmJSzZD/az35TdwuDr
f1nb9nZMG+uarLW4TIuzLsM7znZ7DP5lWRSVzbKvUPi0TbGeIW6zjBDx4NMn
z3ifP5v/8z/+5xdIIcJRnukmAL4dgibGms1nC8ZLRxJT9jmmP2aLvL60AENZ
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

-->

</rfc>

