<?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-blobext-02" category="std" consensus="true" submissionType="IETF" obsoletes="9404" updates="8620" tocInclude="true" sortRefs="true" symRefs="true">
  <front>
    <title abbrev="JMAP Blob">JMAP Blob Management</title>

    <author initials="B." surname="Gondwana" fullname="Bron Gondwana">
      <organization>Fastmail</organization>
      <address>
        <email>brong@fastmailteam.com</email>
      </address>
    </author>

    <date year="2026" month="October" day="14"/>

    
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<?line 30?>

<t>The JSON Meta Application Protocol (JMAP) base protocol (<xref target="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 "blob".</t>

<t>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>

  <middle>


<?line 44?>

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

<t>Sometimes JMAP (<xref target="JMAP-CORE"/>) interactions require creating a blob and then
referencing it.  Embedding blobs directly into the JMAP method calls array
can reduce round trips.</t>

<t>Likewise, when fetching an object, it can be useful to also fetch the raw
content of that object without a separate round trip.</t>

<t>When JMAP is proxied through a system that applies additional access
restrictions, it can be useful to know which objects reference any particular
blob; this document defines a way to discover those references.</t>

<t>For large blobs, a client may wish to upload data in chunks and have the
server assemble them efficiently, or retrieve information about how the server
has stored a blob internally.</t>

<t>Many applications also benefit from server-side transformations — converting
images, creating or unpacking archives, compressing or decompressing data, or
computing and applying deltas — without needing to download and re-upload
blob content.</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 one additional capability URI.</t>

<section anchor="urnietfparamsjmapblob2"><name>urn:ietf:params:jmap:blob2</name>

<t>The capability <spanx style="verb">urn:ietf:params:jmap:blob2</spanx> being present in the
"accountCapabilities" property of an account represents support for
the blob methods defined in this document: Blob/set, Blob/get,
Blob/lookup, and Blob/convert.  Servers that include this capability
in one or more "accountCapabilities" properties <bcp14>MUST</bcp14> also include it
in the "capabilities" property.</t>

<t>A server <bcp14>MAY</bcp14> also advertise <spanx style="verb">urn:ietf:params:jmap:blob</spanx> (as defined
in RFC9404) to support older clients, but a client <bcp14>MUST NOT</bcp14> include
both <spanx style="verb">urn:ietf:params:jmap:blob</spanx> and <spanx style="verb">urn:ietf:params:jmap:blob2</spanx>
in the <spanx style="verb">using</spanx> array of the same request.  The blob2 capability
supersedes the blob capability and does not depend on it.</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 and permissions for that account:</t>

<t><list style="symbols">
  <t>maxSizeBlobSet: "UnsignedInt|null"  <vspace blankLines='1'/>
The maximum size of a blob (in octets) that the server will
  allow to be created (including blobs created by concatenating
  multiple data sources together).  If null, the server does not
  advertise a specific limit but <bcp14>MAY</bcp14> still reject blobs that are
  too large.</t>
  <t>maxDataSources: "UnsignedInt"  <vspace blankLines='1'/>
The maximum number of DataSourceObjects allowed in the <spanx style="verb">data</spanx>
  array of a single creation in Blob/set.  Servers <bcp14>MUST</bcp14> support
  at least 64 DataSourceObjects per creation.</t>
  <t>supportedTypeNames: "String[]"  <vspace blankLines='1'/>
An array of data type names that the server supports for
  Blob/lookup.  The values are the names listed in the IANA "JMAP
  Data Types" registry.  If the array is empty, the server does
  not support Blob/lookup.  Servers <bcp14>MAY</bcp14> include private type names
  not in the registry; clients <bcp14>MUST</bcp14> ignore names they do not
  recognise.  Clients <bcp14>MUST</bcp14> also ignore names that they do
  recognise if the corresponding capability for that type name
  is not present in the 'capabilities' section of the session
  object, because that means that the name has been used as a
  private type rather than a capability that the client knows.</t>
  <t>supportedDigestAlgorithms: "String[]"  <vspace blankLines='1'/>
An array of digest algorithms supported for Blob/get, from the
  IANA "Hash Function Textual Names" registry, expressed in
  lowercase (e.g., "sha", "sha-256").  Clients <bcp14>SHOULD</bcp14> prefer
  algorithms listed earlier in the array.</t>
  <t>uploadUrl: "String|null"  <vspace blankLines='1'/>
A URI template (optionally containing <spanx style="verb">{accountId}</spanx>) for
  uploading blobs via HTTP POST for this account, in the same
  format as the session-level <spanx style="verb">uploadUrl</spanx> defined in
  <xref target="JMAP-CORE"/>, Section 2.  Servers <bcp14>MUST</bcp14> still provide the
  session-level <spanx style="verb">uploadUrl</spanx>; this per-account URL is an
  alternative that <bcp14>MAY</bcp14> point to a different server or be more
  efficient for this account.  Uploads to this URL return a JSON
  object with the same properties as the session-level upload
  response, plus an <spanx style="verb">expires</spanx> property as defined in "The expires
  Response Property" below.  If null, clients <bcp14>SHOULD</bcp14> use the
  session-level <spanx style="verb">uploadUrl</spanx>.</t>
  <t>chunkSize: "UnsignedInt|null"  <vspace blankLines='1'/>
A hint indicating the preferred chunk size in octets.  If a
  client uploads blobs with exactly this size except for the
  final chunk, and uses Blob/set with DataSourceObjects
  referencing these chunks, the server can optimise storage of
  these chunks.  Servers <bcp14>MUST</bcp14> allow other sizes for the
  individual data blocks in Blob/set though, and will then
  choose whether to store them as an array of blobs still, or
  to combine them.</t>
  <t>supportedImageReadTypes: "String[]|null"  <vspace blankLines='1'/>
The media types (<xref target="MEDIA-TYPES"/>) that the server can read as
  input to ImageConvertRecipe.  If null, the server does not
  support image conversion.</t>
  <t>supportedImageWriteTypes: "String[]|null"  <vspace blankLines='1'/>
The media types (<xref target="MEDIA-TYPES"/>) that the server can produce
  as output from ImageConvertRecipe.  If null, the server does
  not support image conversion.</t>
  <t>supportedArchiveTypes: "String[]|null"  <vspace blankLines='1'/>
The archive media types (<xref target="MEDIA-TYPES"/>) supported for creating
  archives via ArchiveRecipe.  If null, the server does not support
  archive creation.</t>
  <t>supportedExtractTypes: "String[]|null"  <vspace blankLines='1'/>
The archive MIME types supported for extracting archives via
  ExtractRecipe.  This <bcp14>MAY</bcp14> include types not in
  <spanx style="verb">supportedArchiveTypes</spanx> (e.g., "application/vnd.ms-tnef").
  If null, the server does not support archive extraction.</t>
  <t>supportedCompressTypes: "String[]|null"  <vspace blankLines='1'/>
The compression media types (<xref target="MEDIA-TYPES"/>) supported for
  compressing via CompressRecipe.  If null, the server does not
  support compression.</t>
  <t>supportedDecompressTypes: "String[]|null"  <vspace blankLines='1'/>
The compression MIME types supported for decompressing via
  DecompressRecipe.  This <bcp14>MAY</bcp14> include types not in
  <spanx style="verb">supportedCompressTypes</spanx>.  If null, the server does not
  support decompression.</t>
  <t>supportedDeltaTypes: "String[]|null"  <vspace blankLines='1'/>
The delta media types (<xref target="MEDIA-TYPES"/>) supported for computing
  deltas via DeltaRecipe.  If null, the server does not support
  delta computation.</t>
  <t>supportedPatchTypes: "String[]|null"  <vspace blankLines='1'/>
The delta media types supported for applying patches via
  PatchRecipe.  This <bcp14>MAY</bcp14> include types not in
  <spanx style="verb">supportedDeltaTypes</spanx>.  If null, the server does not
  support patch application.</t>
  <t>maxConvertSize: "UnsignedInt|null"  <vspace blankLines='1'/>
If supplied, the maximum size in octets of any single input
  blob to a Blob/convert operation.  Requests referencing a blob
  larger than this value <bcp14>MUST</bcp14> be rejected with a "tooLarge"
  SetError.  If null, the server does not advertise a specific
  limit but <bcp14>MAY</bcp14> still reject blobs that are too large.</t>
  <t>maxArchiveEntries: "UnsignedInt|null"  <vspace blankLines='1'/>
If supplied, the maximum number of entries allowed in an
  ArchiveRecipe.  Requests exceeding this limit <bcp14>MUST</bcp14> be rejected
  with a "tooLarge" SetError.  If null, the server does not
  advertise a specific limit but <bcp14>MAY</bcp14> still reject requests with
  too many entries.</t>
  <t>maxImageDimension: "UnsignedInt|null"  <vspace blankLines='1'/>
If supplied, the maximum value accepted for <spanx style="verb">width</spanx> or <spanx style="verb">height</spanx>
  in an ImageConvertRecipe, in pixels.  Requests exceeding this
  limit <bcp14>MUST</bcp14> be rejected with a "tooLarge" SetError.  If null,
  the server does not advertise a specific limit but <bcp14>MAY</bcp14> still
  reject requests with dimensions that are too large.</t>
</list></t>

<section anchor="capability-example"><name>Capability Example</name>

<figure><sourcecode type="json"><![CDATA[
{
  "urn:ietf:params:jmap:blob2": {
    "maxSizeBlobSet": 52428800,
    "maxDataSources": 64,
    "supportedTypeNames": ["Email", "Thread", "Mailbox"],
    "supportedDigestAlgorithms": ["sha-256", "sha"],
    "uploadUrl": "https://upload.example.com/jmap/upload/{accountId}/",
    "chunkSize": 5242880,
    "supportedImageReadTypes": [
      "image/png",
      "image/jpeg",
      "image/gif",
      "image/tiff"
    ],
    "supportedImageWriteTypes": [
      "image/png",
      "image/jpeg"
    ],
    "supportedArchiveTypes": [
      "application/zip",
      "application/x-tar"
    ],
    "supportedExtractTypes": [
      "application/zip",
      "application/x-tar",
      "application/vnd.ms-tnef"
    ],
    "supportedCompressTypes": [
      "application/gzip",
      "application/zstd"
    ],
    "supportedDecompressTypes": [
      "application/gzip",
      "application/x-bzip2",
      "application/zstd"
    ],
    "supportedDeltaTypes": [
      "application/x-rdiff-delta",
      "text/x-diff"
    ],
    "supportedPatchTypes": [
      "application/x-rdiff-delta",
      "text/x-diff"
    ],
    "maxConvertSize": 104857600,
    "maxArchiveEntries": 10000,
    "maxImageDimension": 8192
  }
}
]]></sourcecode></figure>

</section>
</section>
</section>
<section anchor="datasourceobject"><name>DataSourceObject</name>

<t>A DataSourceObject describes a source of data for use in Blob/set.
It <bcp14>MUST</bcp14> contain exactly one of either <spanx style="verb">data:asText</spanx> or <spanx style="verb">data:asBase64</spanx>
(for inline data) or <spanx style="verb">blobId</spanx> (for a reference to an existing blob).
The <spanx style="verb">data:asText</spanx> and <spanx style="verb">data:asBase64</spanx> properties <bcp14>MUST NOT</bcp14> both be
present in the same DataSourceObject.</t>

<t><list style="symbols">
  <t>data:asText: "String|null"  <vspace blankLines='1'/>
The data represented as a UTF-8 string.  The server <bcp14>MUST</bcp14> reject
  the creation with a "notCreated" response if the value is not
  valid UTF-8.</t>
  <t>data:asBase64: "String|null"  <vspace blankLines='1'/>
The data encoded as base64 (<xref target="BASE64"/>).  The server <bcp14>MUST</bcp14> reject
  the creation with a "notCreated" response if the value is not
  valid base64.</t>
  <t>blobId: "BlobId"  <vspace blankLines='1'/>
The blobId of an existing blob whose octets are to be copied
  into the new blob.</t>
  <t>offset: "UnsignedInt|null"  <vspace blankLines='1'/>
The offset (in octets) within the data source from which to
  start copying.  If null, defaults to 0 (the start of the data
  source).  If the range cannot be fully satisfied (i.e., it
  begins or extends past the end of the data), the DataSourceObject
  is invalid and the creation <bcp14>MUST</bcp14> be rejected with a "notCreated"
  response.</t>
  <t>length: "UnsignedInt|null"  <vspace blankLines='1'/>
The number of octets to copy from the data source.  If null,
  copy from <spanx style="verb">offset</spanx> to the end of the data source.  If the range
  cannot be fully satisfied, the DataSourceObject is invalid and
  the creation <bcp14>MUST</bcp14> be rejected with a "notCreated" response.</t>
  <t>size: "UnsignedInt|null"  <vspace blankLines='1'/>
The full size of the data source in octets.  In the <spanx style="verb">chunks</spanx>
  array of a Blob/get response this is the size of the underlying
  chunk blob.</t>
  <t>position: "UnsignedInt|null"  <vspace blankLines='1'/>
The byte offset of the start of this data source within the
  outer (containing) blob.  Only meaningful in the <spanx style="verb">chunks</spanx> array
  of a Blob/get response.  This value is redundant with the sum of
  the <spanx style="verb">length</spanx> values of the preceding chunks, but it allows a
  client to locate the chunk covering a particular byte range
  without fetching or summing every earlier chunk, and when a
  DataSourceObject is reused in Blob/set it acts as a consistency
  check that the chunk is being placed where the client expects.</t>
</list></t>

<t>A DataSourceObject in the <spanx style="verb">chunks</spanx> array of a Blob/get response <bcp14>MAY</bcp14>
also include <spanx style="verb">digest:*</spanx> properties (e.g. <spanx style="verb">digest:sha-256</spanx>) when
those names are included in the <spanx style="verb">dataSourceProperties</spanx> request
argument.  Each digest value is computed over the octets that the
chunk contributes to the blob (i.e. after applying <spanx style="verb">offset</spanx> and
<spanx style="verb">length</spanx>).</t>

<t>When a server provides <spanx style="verb">size</spanx>, <spanx style="verb">position</spanx>, or <spanx style="verb">digest:*</spanx> values in
a Blob/get response, it <bcp14>MUST</bcp14> calculate them correctly.  When a
DataSourceObject containing <spanx style="verb">size</spanx>, <spanx style="verb">position</spanx>, or <spanx style="verb">digest:*</spanx> values
is used in Blob/set, the server <bcp14>MUST</bcp14> reject the object if any
provided value does not match the actual data.</t>

</section>
<section anchor="blobset"><name>Blob/set</name>

<t>Blob/set is defined under the <spanx style="verb">urn:ietf:params:jmap:blob2</spanx> capability
and requires that capability in the request's <spanx style="verb">using</spanx> array.</t>

<t>This method creates, touches, and destroys blobs.  It is a standard
Foo/set method (<xref target="JMAP-CORE"/>, Section 5.3) with the following
blob-specific behaviours:</t>

<t><list style="symbols">
  <t>create: "Id[BlobCreateObject]|null"  <vspace blankLines='1'/>
A map of a creation id to a BlobCreateObject describing the blob
  to create, or null if no blobs are to be created.</t>
  <t>update: A map of blobId to a patch object.  The only property a
client can request to change is <spanx style="verb">expires</spanx>; all other properties can
only be set to their existing values.  The server can honour the
requested <spanx style="verb">expires</spanx> (by not returning an <spanx style="verb">expires</spanx> in the updated
BlobObject) or return a different <spanx style="verb">expires</spanx> value if it applied a
different lifetime.  The purpose of update is to "touch" the blob,
refreshing its lifetime on the server.  If the blobId does not
exist, it <bcp14>MUST</bcp14> be reported in a <spanx style="verb">notUpdated</spanx> map with a "notFound"
SetError.</t>
  <t>destroy: The server <bcp14>MUST</bcp14> reject any blob that is still referenced
by another object with a "blobHasReference" SetError.</t>
</list></t>

<t>An BlobCreateObject has the following properties:</t>

<t><list style="symbols">
  <t>data: "DataSourceObject[]"  <vspace blankLines='1'/>
An array of zero or more DataSourceObjects.  The new blob is
  formed by concatenating the data described by each DataSourceObject
  in the order given.</t>
  <t>type: "String|null" (default: null)  <vspace blankLines='1'/>
A media type hint (<xref target="MEDIA-TYPES"/>) for the blob.  The server
  <bcp14>MAY</bcp14> use this when setting the Content-Type of a subsequent
  download of the blob, but is not required to.  The server <bcp14>MAY</bcp14>
  infer the type itself and override the client's hint.</t>
  <t>noPersist: "Boolean" (default: false)  <vspace blankLines='1'/>
If true, the resulting blob is ephemeral: it may be referenced
  via creation id backreferences within the same JMAP request,
  but the server is not required to persist it beyond the lifetime
  of the request.  The server <bcp14>MAY</bcp14> omit ephemeral blobs from the
  <spanx style="verb">created</spanx> map of the response and from the <spanx style="verb">createdIds</spanx> of the
  final Response object if it did not create a referenceable blob.
  This allows servers to optimise pipelines where intermediate
  blobs are never needed after the request completes.</t>
</list></t>

<t>The server <bcp14>MUST NOT</bcp14> guess the user's intent when a DataSourceObject is
invalid (e.g., contains non-UTF-8 data in <spanx style="verb">data:asText</spanx> or invalid
base64 in <spanx style="verb">data:asBase64</spanx>).  It <bcp14>MUST</bcp14> reject the creation and return a
"notCreated" response for that creation id.</t>

<t>The response is a standard Foo/set response.  The objects in the
<spanx style="verb">created</spanx> and <spanx style="verb">updated</spanx> maps are BlobObjects.  If an update set a
new <spanx style="verb">expires</spanx>, the server returns a BlobObject with the actual
<spanx style="verb">expires</spanx> that was applied; if the server accepted the requested
value it need not return an <spanx style="verb">expires</spanx> in the BlobObject.</t>

<t>A BlobObject has the following properties:</t>

<t><list style="symbols">
  <t>id: "BlobId"  <vspace blankLines='1'/>
The id of the blob.</t>
  <t>type: "String|null"  <vspace blankLines='1'/>
The media type of the blob, or null if unknown.</t>
  <t>size: "UnsignedInt"  <vspace blankLines='1'/>
The size of the blob in octets.</t>
  <t>expires: "UTCDate|null"  <vspace blankLines='1'/>
See "The expires Response Property" below.</t>
</list></t>

</section>
<section anchor="blobget"><name>Blob/get</name>

<t>Blob/get is defined under the <spanx style="verb">urn:ietf:params:jmap:blob2</spanx> capability
and requires that capability in the request's <spanx style="verb">using</spanx> array.</t>

<t>This method retrieves blob data.  It is a standard Foo/get method
(<xref target="JMAP-CORE"/>, Section 5.1) with the following additional parameters
and a custom response.</t>

<t>In addition to the standard <spanx style="verb">accountId</spanx>, <spanx style="verb">ids</spanx>, and <spanx style="verb">properties</spanx>
arguments, Blob/get accepts:</t>

<t><list style="symbols">
  <t>offset: "UnsignedInt|null" (default: null)  <vspace blankLines='1'/>
The starting byte position within the blob.  If null, defaults
  to 0.</t>
  <t>length: "UnsignedInt|null" (default: null)  <vspace blankLines='1'/>
The number of bytes to return.  If null, returns all bytes from
  <spanx style="verb">offset</spanx> to the end of the blob.</t>
  <t>dataSourceProperties: "String[]" (default: ["blobId", "size"])  <vspace blankLines='1'/>
If supplied, only the properties listed in the array are returned
  for each DataSourceObject in the <spanx style="verb">chunks</spanx> array.  This argument
  has no effect unless <spanx style="verb">chunks</spanx> is included in <spanx style="verb">properties</spanx>.  Available
  properties include <spanx style="verb">blobId</spanx>, <spanx style="verb">size</spanx>, <spanx style="verb">offset</spanx>, <spanx style="verb">length</spanx>,
  <spanx style="verb">position</spanx>, and <spanx style="verb">digest:*</spanx> values where <spanx style="verb">*</spanx> is a hash algorithm
  name from the IANA "Hash Function Textual Names" registry (e.g.
  <spanx style="verb">digest:sha-256</spanx>).</t>
</list></t>

<t>The requestable properties in the <spanx style="verb">properties</spanx> array are:</t>

<t><list style="symbols">
  <t>data:asText  <vspace blankLines='1'/>
The data in the selected range as a UTF-8 string.  If the
  selected bytes are not valid UTF-8 (including truncation in the
  middle of a multi-octet sequence), the response value is null
  and <spanx style="verb">isEncodingProblem</spanx> is set to true.</t>
  <t>data:asBase64  <vspace blankLines='1'/>
The data in the selected range encoded as base64 (<xref target="BASE64"/>).</t>
  <t>data  <vspace blankLines='1'/>
Returns <spanx style="verb">data:asText</spanx> if the selected bytes are valid UTF-8,
  otherwise returns <spanx style="verb">data:asBase64</spanx>.</t>
  <t>digest:&lt;algorithm&gt;  <vspace blankLines='1'/>
The base64-encoded digest of the selected range, computed using
  the named algorithm.  The algorithm name <bcp14>MUST</bcp14> appear in the
  server's <spanx style="verb">supportedDigestAlgorithms</spanx> capability.</t>
  <t>size  <vspace blankLines='1'/>
The total size of the blob in octets, regardless of the range
  selected.</t>
  <t>imageData  <vspace blankLines='1'/>
If the blob is an image or video type and the server can
  extract metadata, this is an ImageData object.  Otherwise
  null.  Only returned if explicitly requested in <spanx style="verb">properties</spanx>.
  The server <bcp14>MAY</bcp14> need to read the blob content to compute this
  data, so clients <bcp14>SHOULD</bcp14> only request it when needed.  Since
  blobs are immutable, the result for a given blobId will never
  change, and the server <bcp14>SHOULD</bcp14> cache it.  <vspace blankLines='1'/>
An ImageData object has the following properties:  <list style="symbols">
      <t>width: "UnsignedInt|null"
Width of the image in pixels, if known.</t>
      <t>height: "UnsignedInt|null"
Height of the image in pixels, if known.</t>
      <t>orientation: "UnsignedInt|null"
EXIF orientation value (1-8) as defined in the EXIF
specification (CIPA DC-008).  If present, indicates how
the image should be rotated/flipped for display.</t>
      <t>date: "UTCDate|null"
Date the image or video was captured (from EXIF
DateTimeOriginal or equivalent), if present.</t>
      <t>gps: "ImageGPS|null"
GPS coordinates from EXIF, if present.  An ImageGPS
object has the following properties:
      <list style="symbols">
          <t>latitude: "Number" — Latitude in decimal degrees.</t>
          <t>longitude: "Number" — Longitude in decimal degrees.</t>
        </list></t>
      <t>duration: "Number|null"
Duration in seconds for video content, if known.  This
is a floating-point number to allow sub-second precision.</t>
      <t>comment: "String|null"
Embedded EXIF comment or description, if present.  This
is read-only — it reflects the metadata stored in the
blob content and is not a user-editable property.</t>
    </list></t>
  <t>chunks  <vspace blankLines='1'/>
An array of DataSourceObjects describing the internal chunk
  structure of the blob (see below).  Only returned if explicitly
  requested in <spanx style="verb">properties</spanx>.  The properties returned for each
  DataSourceObject are controlled by the <spanx style="verb">dataSourceProperties</spanx>
  argument.</t>
</list></t>

<t>If neither <spanx style="verb">offset</spanx> nor <spanx style="verb">length</spanx> are specified (i.e., both null),
the default properties are <spanx style="verb">data</spanx> and <spanx style="verb">size</spanx>.  Otherwise, the client
<bcp14>MUST</bcp14> specify the <spanx style="verb">properties</spanx> to return.</t>

<t>The response contains a <spanx style="verb">list</spanx> of objects, one per blobId.  Each
object contains the requested properties plus:</t>

<t><list style="symbols">
  <t>id: "BlobId"  <vspace blankLines='1'/>
The blobId of the blob.</t>
  <t>isEncodingProblem: "Boolean" (default: false)  <vspace blankLines='1'/>
Set to true if <spanx style="verb">data</spanx> or <spanx style="verb">data:asText</spanx> was requested but the
  selected range is not valid UTF-8.</t>
  <t>isTruncated: "Boolean" (default: false)  <vspace blankLines='1'/>
Set to true if the selected range extends past the end of the
  blob.  In this case, only the bytes from <spanx style="verb">offset</spanx> to the end of
  the blob (or an empty string if <spanx style="verb">offset</spanx> is past the end) are
  returned.</t>
  <t>chunks: "DataSourceObject[]"  <vspace blankLines='1'/>
Present only if <spanx style="verb">chunks</spanx> was requested in <spanx style="verb">properties</spanx>.  An
  array of one or more data source objects describing the internal
  chunk structure of the blob.  The blob is reconstructed by
  concatenating the data from each data source object in the
  listed order.  The client <bcp14>MUST</bcp14> use the <spanx style="verb">offset</spanx> and <spanx style="verb">length</spanx>
  of each DataSourceObject to determine which octets to read from
  each chunk's underlying blob.  <vspace blankLines='1'/>
A server that does not store the blob in chunks returns
  a single DataSourceObject covering the entire blob, with
  <spanx style="verb">blobId</spanx> set to the blob's own id, <spanx style="verb">offset</spanx> 0, <spanx style="verb">length</spanx> and
  <spanx style="verb">size</spanx> equal to the size of the blob, and <spanx style="verb">position</spanx> 0.  This
  allows clients to process the <spanx style="verb">chunks</spanx> array the same way
  regardless of how the server stores blobs.</t>
</list></t>

<t>The response also contains:</t>

<t><list style="symbols">
  <t>accountId: "Id"  <vspace blankLines='1'/>
The id of the account used for the operation.</t>
  <t>notFound: "Id[]"  <vspace blankLines='1'/>
An array of blobIds that were not found.</t>
</list></t>

</section>
<section anchor="bloblookup"><name>Blob/lookup</name>

<t>Blob/lookup is defined under the <spanx style="verb">urn:ietf:params:jmap:blob2</spanx>
capability and requires that capability in the request's <spanx style="verb">using</spanx>
array.</t>

<t>This method provides a reverse lookup: given a set of blobIds, it
returns which objects of specified data types reference those blobs.</t>

<t>The method takes the following arguments:</t>

<t><list style="symbols">
  <t>accountId: "Id"  <vspace blankLines='1'/>
The id of the account to use.</t>
  <t>typeNames: "String[]"  <vspace blankLines='1'/>
A list of data type names to search.  Only type names listed in
  the server's <spanx style="verb">supportedTypeNames</spanx> capability are valid.  If a
  type name is not known by the server or the associated capability
  has not been requested in <spanx style="verb">using</spanx>, the server <bcp14>MUST</bcp14> return an
  "unknownDataType" error.</t>
  <t>ids: "BlobId[]"  <vspace blankLines='1'/>
The blobIds to look up.</t>
</list></t>

<t>The response contains:</t>

<t><list style="symbols">
  <t>accountId: "Id"  <vspace blankLines='1'/>
The id of the account used for the operation.</t>
  <t>list: "BlobInfo[]"  <vspace blankLines='1'/>
A list of BlobInfo objects, one per blobId.  A BlobInfo object
  has the following properties:  <list style="symbols">
      <t>id: "BlobId"
The blobId queried.</t>
      <t>matchedIds: "String[Id[]]"
An object mapping each requested type name to an array of
object ids of that type that reference this blob.  If no
objects of that type reference this blob, the array is empty.</t>
    </list></t>
</list></t>

<t>Access control: if a blob is not visible to the authenticated user or
does not exist on the server at all, the server <bcp14>MUST</bcp14> still return an
empty array for each type name.  This ensures that the response does
not reveal whether the blob exists but is inaccessible to the user.</t>

</section>
<section anchor="the-expires-response-property"><name>The "expires" Response Property</name>

<t>The Blob/set response and the Blob/convert response include the
following property on each BlobObject:</t>

<t><list style="symbols">
  <t>expires: "UTCDate|null"  <vspace blankLines='1'/>
A hint from the server indicating the likely availability of
  the blob.  The blob is likely to remain available until this
  time, and likely not to be available after it.  This is not a
  guarantee in either direction: the server <bcp14>MAY</bcp14> garbage collect
  the blob before this time if it is unreferenced, and <bcp14>MAY</bcp14>
  retain it longer.  If null, the server does not have a
  specific expiry time for the blob.</t>
</list></t>

<t>Clients that need the blob to persist beyond the <spanx style="verb">expires</spanx> time
should reference it from a persistent object (e.g., a FileNode
or an Email) before it expires.</t>

</section>
<section anchor="blobconvert"><name>Blob/convert</name>

<t>Blob/convert is defined under the <spanx style="verb">urn:ietf:params:jmap:blob2</spanx>
capability and requires that capability in the request's <spanx style="verb">using</spanx>
array.</t>

<t>Blob/convert performs server-side transformations on blobs.  Like
Blob/set, it takes an <spanx style="verb">accountId</spanx> and a <spanx style="verb">create</spanx> argument that maps
creation ids to conversion request objects.</t>

<t>Each conversion request object <bcp14>MAY</bcp14> also include the following property:</t>

<t><list style="symbols">
  <t>noPersist: "Boolean" (default: false)
If true, the resulting blob is ephemeral: it may be referenced via
creation id backreferences within the same JMAP request, but the
server is not required to persist it beyond the lifetime of the
request.  The server <bcp14>MAY</bcp14> omit ephemeral blobs from the <spanx style="verb">created</spanx>
map of the response and from the <spanx style="verb">createdIds</spanx> of the final Response
object if it did not create a referenceable blob.</t>
</list></t>

<t>Each conversion request object <bcp14>MUST</bcp14> contain exactly one of the
following properties, which determines the type of conversion:</t>

<t><list style="symbols">
  <t>imageConvert: ImageConvertRecipe</t>
  <t>archive: ArchiveRecipe</t>
  <t>extract: ExtractRecipe</t>
  <t>compress: CompressRecipe</t>
  <t>decompress: DecompressRecipe</t>
  <t>delta: DeltaRecipe</t>
  <t>patch: PatchRecipe</t>
</list></t>

<t>The response has the same structure as Blob/set: a <spanx style="verb">created</spanx> map of
creation id to a BlobObject for each successful conversion, and a
<spanx style="verb">notCreated</spanx> map of creation id to a SetError object for each failed
conversion.  The <spanx style="verb">id</spanx> is the blobId of the created blob.  The
response also includes an <spanx style="verb">expires</spanx> property on each BlobObject (see
"The expires Response Property" above).</t>

<t>If the conversion completed but encountered problems (e.g., a
corrupt archive where some entries extracted successfully but
others did not, or a truncated compressed stream that partially
decompressed), the response for that creation also includes:</t>

<t><list style="symbols">
  <t>isIncomplete: "Boolean" (default: false)
If true, the conversion did not complete cleanly.  The output
blob may be partial or missing some content.</t>
  <t>description: "String|null"
A human-readable description of the problem, if any.</t>
</list></t>

<t>If the conversion failed entirely and no usable output could be
produced, the server <bcp14>MUST</bcp14> return a <spanx style="verb">conversionFailed</spanx> SetError
in the <spanx style="verb">notCreated</spanx> map.</t>

<t>Creation id backreferences (using the <spanx style="verb">#</spanx> prefix) resolve to
the <spanx style="verb">id</spanx> of the created blob and may be used in subsequent
conversions within the same Blob/convert call or in later
method calls within the same JMAP request.</t>

<t>A server <bcp14>MAY</bcp14> return a blobId for a conversion result without
immediately generating the output data.  In this case the server
<bcp14>MUST</bcp14> generate the data when the blob is later accessed (e.g., via
a download request or as input to another operation).  This allows
the server to respond quickly to Blob/convert requests while
deferring expensive work such as image resizing or archive
creation.  The returned blobId <bcp14>MUST</bcp14> be usable in all contexts
where a regular blobId is accepted.  If the deferred generation
later fails (e.g., the source blob has expired), the server
<bcp14>SHOULD</bcp14> return an appropriate HTTP error when the blob is
downloaded.  If the exact size of the output is not yet known, the
server <bcp14>MUST</bcp14> omit the <spanx style="verb">size</spanx> property from the response for that
creation.  If a client later requests the <spanx style="verb">size</spanx> property via
Blob/get for a deferred blob, the server <bcp14>MUST</bcp14> generate the blob
at that point and return the actual size.</t>

<t>The server <bcp14>MUST</bcp14> resolve the order of dependencies between entries
in the <spanx style="verb">create</spanx> map and process them in an order such that all
backreferences are satisfied.  If a dependency cycle is detected,
all members of the cycle <bcp14>MUST</bcp14> be rejected with an
"invalidProperties" error.</t>

<section anchor="imageconvertrecipe"><name>ImageConvertRecipe</name>

<t>An ImageConvertRecipe converts an image blob to a different format
or size.  It is an object with the following properties:</t>

<t><list style="symbols">
  <t>blobId: "BlobId"
The blobId of the source image.</t>
  <t>type: "String"
Media type (<xref target="MEDIA-TYPES"/>) of the image to create (e.g.
"image/png").  <bcp14>MUST</bcp14> be one of the values in the server's
<spanx style="verb">supportedImageWriteTypes</spanx> capability.  The source image <bcp14>MUST</bcp14>
be in a format listed in <spanx style="verb">supportedImageReadTypes</spanx>.</t>
  <t>width: "UnsignedInt|null"
Maximum width in pixels of the image to create.  If null, the
server preserves the source width (or scales proportionally if
only <spanx style="verb">height</spanx> is given).</t>
  <t>height: "UnsignedInt|null"
Maximum height in pixels of the image to create.  If null, the
server preserves the source height (or scales proportionally if
only <spanx style="verb">width</spanx> is given).</t>
  <t>ignoreAspect: "Boolean|null"
If true, resize to exactly the given width and height, even if
the aspect ratio is changed.  If null or false, the image is
scaled to fit within the given dimensions while preserving the
aspect ratio.</t>
  <t>quality: "UnsignedInt|null"
Compression quality for lossy formats, as a value from 1 (lowest
quality, smallest file) to 100 (highest quality, largest file).
Only meaningful for formats that support lossy compression such as
image/jpeg and image/webp.  If null, the server selects a sensible
default.</t>
  <t>colorSpace: "String|null"
The color space for the output image.  Defined values are "sRGB"
and "grayscale".  If null, the server preserves the source image's
color space where possible.</t>
  <t>background: "String|null"
A fill color to use when the source image has transparency but the
target format does not support it (e.g. converting PNG to JPEG).
The value is a CSS-style hex color string (e.g. "#ffffff" for white).
If null, the server selects a sensible default (typically white).</t>
  <t>stripMetadata: "Boolean|null"
If true, strip image metadata such as EXIF, XMP, and IPTC data from
the output.  If null or false, the server preserves metadata where
the target format supports it.</t>
  <t>autoOrient: "Boolean|null"
If true, automatically rotate and flip the image according to its
EXIF orientation tag, then reset the tag.  If null or false, the
image data is not reoriented.</t>
</list></t>

<t>Errors:</t>

<t><list style="symbols">
  <t>"notFound" — the referenced blobId does not exist.</t>
  <t>"invalidProperties" — the type is not in
<spanx style="verb">supportedImageWriteTypes</spanx>, or the source blob is not in a format
listed in <spanx style="verb">supportedImageReadTypes</spanx>.</t>
  <t>"tooLarge" — the source blob exceeds <spanx style="verb">maxConvertSize</spanx>, or the
requested dimensions exceed <spanx style="verb">maxImageDimension</spanx>.</t>
  <t>"conversionFailed" — the image conversion failed entirely.</t>
</list></t>

</section>
<section anchor="archiverecipe"><name>ArchiveRecipe</name>

<t>An ArchiveRecipe creates an archive blob from a list of entries.
It is an object with the following properties:</t>

<t><list style="symbols">
  <t>type: "String"
The media type (<xref target="MEDIA-TYPES"/>) of the archive to create.  <bcp14>MUST</bcp14> be
one of the values in the server's <spanx style="verb">supportedArchiveTypes</spanx> capability.</t>
  <t>entries: "ArchiveEntry[]"
An array of ArchiveEntry objects describing the contents of the
archive.</t>
</list></t>

<t>Errors:</t>

<t><list style="symbols">
  <t>"notFound" — a referenced entry blobId does not exist.</t>
  <t>"invalidProperties" — the type is not in <spanx style="verb">supportedArchiveTypes</spanx>;
an entry has an unsupported entryType for the archive format; or
a required field (e.g. linkTarget for symlink entries) is missing.</t>
  <t>"tooLarge" — the number of entries exceeds <spanx style="verb">maxArchiveEntries</spanx>,
or a referenced blob exceeds <spanx style="verb">maxConvertSize</spanx>.</t>
  <t>"conversionFailed" — the archive creation failed entirely.</t>
</list></t>

</section>
<section anchor="archiveentry"><name>ArchiveEntry</name>

<t>An ArchiveEntry describes a single entry in an archive.  It is used
both as input (in ArchiveRecipe) and as output (in ExtractRecipe
results).  It is an object with the following properties:</t>

<t><list style="symbols">
  <t>name: "String"
The path of the entry within the archive.  Directory entries <bcp14>MUST</bcp14>
have a name ending with "/".</t>
  <t>blobId: "BlobId|null"
The blobId of the content for this entry.  <bcp14>MUST</bcp14> be non-null for
file entries.  <bcp14>MUST</bcp14> be null or absent for directory, symlink,
hardlink, fifo, and device entries.  Violating these constraints
is an "invalidProperties" error.</t>
  <t>entryType: "String|null"
The type of the entry.  If null, defaults to "file".  Defined values
are "file" (a regular file, the default), "directory", "symlink"
(a symbolic link), "hardlink" (a hard link), "fifo" (a named pipe),
"blockDevice" (a block device node), and "charDevice" (a character
device node).  The server <bcp14>MUST</bcp14> reject entries with unsupported
types for the chosen archive format with an "invalidProperties"
error.</t>
  <t>modified: "UTCDate|null"
The modification time of the entry as an RFC 3339 timestamp.
If null, defaults to the current server time.</t>
  <t>linkTarget: "String|null"
The target path for symlink and hardlink entries.  <bcp14>MUST</bcp14> be non-null
when entryType is "symlink" or "hardlink".  <bcp14>MUST</bcp14> be null for all
other entry types.</t>
  <t>mode: "String|null"
Unix file permissions as an octal string (e.g. "0755", "0644").
If null, the server chooses a reasonable default.  This is
represented as a string rather than an integer to avoid ambiguity
between octal and decimal interpretation.</t>
  <t>uid: "UnsignedInt|null"
The numeric user ID of the entry owner.</t>
  <t>gid: "UnsignedInt|null"
The numeric group ID of the entry owner.</t>
  <t>ownerName: "String|null"
The user name of the entry owner.</t>
  <t>groupName: "String|null"
The group name of the entry owner.</t>
  <t>devMajor: "UnsignedInt|null"
The major device number for "blockDevice" and "charDevice" entries.</t>
  <t>devMinor: "UnsignedInt|null"
The minor device number for "blockDevice" and "charDevice" entries.</t>
  <t>comment: "String|null"
A comment string for this entry.</t>
  <t>compressionMethod: "String|null"
The per-entry compression method.  Defined values are "store" (no
compression) and "deflate".  If null, the server chooses a
reasonable default.</t>
</list></t>

<section anchor="considerations-for-applicationzip"><name>Considerations for application/zip</name>

<t>The zip format only supports "file" and "directory" entry types.
The <spanx style="verb">comment</spanx> and <spanx style="verb">compressionMethod</spanx> properties are only meaningful
for zip archives.  The <spanx style="verb">mode</spanx>, <spanx style="verb">uid</spanx>, <spanx style="verb">gid</spanx>, <spanx style="verb">ownerName</spanx>,
<spanx style="verb">groupName</spanx>, <spanx style="verb">devMajor</spanx>, and <spanx style="verb">devMinor</spanx> properties are ignored.</t>

</section>
<section anchor="considerations-for-applicationx-tar"><name>Considerations for application/x-tar</name>

<t>The tar format supports all entry types.  The <spanx style="verb">mode</spanx>, <spanx style="verb">uid</spanx>, <spanx style="verb">gid</spanx>,
<spanx style="verb">ownerName</spanx>, <spanx style="verb">groupName</spanx>, <spanx style="verb">devMajor</spanx>, and <spanx style="verb">devMinor</spanx> properties are
meaningful for tar archives.  The <spanx style="verb">comment</spanx> and <spanx style="verb">compressionMethod</spanx>
properties are ignored.</t>

<t>Tar archives are not inherently compressed.  To create a compressed
tar archive (e.g. a .tar.gz file), first create the tar archive
using ArchiveRecipe, then compress the result using CompressRecipe.
The following example creates a .tar.gz containing three files in a
single Blob/convert call, using a backreference from the archive
creation to the compression step:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/convert", {
  "accountId": "abc",
  "create": {
    "t1": {
      "archive": {
        "type": "application/x-tar",
        "entries": [
          {
            "name": "site/index.html",
            "blobId": "Baaaa",
            "modified": "2026-03-01T12:00:00Z",
            "mode": "0644"
          },
          {
            "name": "site/logo.png",
            "blobId": "Bbbbb",
            "modified": "2026-02-15T09:30:00Z",
            "mode": "0644"
          },
          {
            "name": "site/style.css",
            "blobId": "Bcccc",
            "modified": "2026-03-01T12:00:00Z",
            "mode": "0644"
          }
        ]
      }
    },
    "t2": {
      "compress": {
        "blobId": "#t1",
        "type": "application/gzip"
      }
    }
  }
}, "0"]]
]]></sourcecode></figure>

</section>
<section anchor="considerations-for-applicationx-cpio"><name>Considerations for application/x-cpio</name>

<t>The cpio format supports all entry types except that <spanx style="verb">ownerName</spanx> and
<spanx style="verb">groupName</spanx> are not supported.  The <spanx style="verb">comment</spanx> and
<spanx style="verb">compressionMethod</spanx> properties are ignored.</t>

</section>
</section>
<section anchor="extractrecipe"><name>ExtractRecipe</name>

<t>An ExtractRecipe extracts the entry listing from an existing archive
blob.  It is an object with the following properties:</t>

<t><list style="symbols">
  <t>blobId: "BlobId"
The blobId of the archive to extract.</t>
  <t>type: "String|null"
The MIME type of the archive format.  If null, the server <bcp14>SHOULD</bcp14>
attempt to auto-detect the format from the blob content (e.g. by
inspecting magic bytes).  If auto-detection fails, the server <bcp14>MUST</bcp14>
return an "unknownFormat" error.</t>
</list></t>

<t>In addition to the standard creation response properties, a
successful ExtractRecipe result includes:</t>

<t><list style="symbols">
  <t>entries: "ArchiveEntry[]"
An array of ArchiveEntry objects describing the contents of the
archive.  Each file entry will have a blobId that can be used to
access the content of that entry.</t>
</list></t>

<t>Errors:</t>

<t><list style="symbols">
  <t>"notFound" — the referenced blobId does not exist.</t>
  <t>"unknownFormat" — the server could not determine or does not support
the archive format.</t>
  <t>"invalidProperties" — the type is not in <spanx style="verb">supportedExtractTypes</spanx>.</t>
  <t>"tooLarge" — the source blob exceeds <spanx style="verb">maxConvertSize</spanx>.</t>
  <t>"conversionFailed" — the extraction failed entirely.</t>
</list></t>

</section>
<section anchor="compressrecipe"><name>CompressRecipe</name>

<t>A CompressRecipe compresses a blob using a specified compression
algorithm.  It is an object with the following properties:</t>

<t><list style="symbols">
  <t>blobId: "BlobId"
The blobId of the data to compress.</t>
  <t>type: "String"
The media type (<xref target="MEDIA-TYPES"/>) of the compression format to use.
<bcp14>MUST</bcp14> be one of the values in the server's <spanx style="verb">supportedCompressTypes</spanx>
capability.</t>
  <t>level: "UnsignedInt|null"
The compression level, where higher values produce smaller output
at the cost of more CPU time.  If null, the server uses the
format's default level.  The valid range depends on the format;
if the requested level is outside the valid range, the server
<bcp14>SHOULD</bcp14> use the nearest valid value.</t>
  <t>checksum: "Boolean|null"
If true, include an integrity checksum in the compressed output.
If null, the server uses the format's default behaviour.</t>
</list></t>

<t>Errors:</t>

<t><list style="symbols">
  <t>"notFound" — the referenced blobId does not exist.</t>
  <t>"invalidProperties" — the type is not in <spanx style="verb">supportedCompressTypes</spanx>.</t>
  <t>"tooLarge" — the source blob exceeds <spanx style="verb">maxConvertSize</spanx>.</t>
  <t>"conversionFailed" — the compression failed entirely.</t>
</list></t>

<section anchor="considerations-for-applicationgzip"><name>Considerations for application/gzip</name>

<t>Compression level ranges from 1 (fastest) to 9 (best compression).
The default is typically 6.  Gzip always includes a CRC-32 checksum;
the <spanx style="verb">checksum</spanx> property is ignored.</t>

</section>
<section anchor="considerations-for-applicationx-bzip2"><name>Considerations for application/x-bzip2</name>

<t>Compression level ranges from 1 (fastest, 100k block size) to 9
(best compression, 900k block size).  The default is typically 9.
Bzip2 always includes a CRC-32 checksum; the <spanx style="verb">checksum</spanx> property is
ignored.</t>

</section>
<section anchor="considerations-for-applicationx-xz"><name>Considerations for application/x-xz</name>

<t>Compression level ranges from 0 (fastest) to 9 (best compression).
The default is typically 6.  Xz always includes an integrity check;
if <spanx style="verb">checksum</spanx> is true the server <bcp14>SHOULD</bcp14> use SHA-256, otherwise CRC-64
is used by default.</t>

</section>
<section anchor="considerations-for-applicationzstd"><name>Considerations for application/zstd</name>

<t>Compression level ranges from 1 (fastest) to 22 (best compression).
The default is typically 3.  If <spanx style="verb">checksum</spanx> is true, an xxHash-64
checksum is included in the frame; the default is false.</t>

</section>
</section>
<section anchor="decompressrecipe"><name>DecompressRecipe</name>

<t>A DecompressRecipe decompresses a compressed blob.  It is an object
with the following properties:</t>

<t><list style="symbols">
  <t>blobId: "BlobId"
The blobId of the compressed data to decompress.</t>
  <t>type: "String|null"
The MIME type of the compression format.  If null, the server <bcp14>SHOULD</bcp14>
attempt to auto-detect the format from magic bytes.  If auto-detection
fails, the server <bcp14>MUST</bcp14> return an "unknownFormat" error.</t>
</list></t>

<t>Errors:</t>

<t><list style="symbols">
  <t>"notFound" — the referenced blobId does not exist.</t>
  <t>"unknownFormat" — the server could not determine or does not support
the compression format.</t>
  <t>"invalidProperties" — the type is not in <spanx style="verb">supportedDecompressTypes</spanx>.</t>
  <t>"tooLarge" — the source blob exceeds <spanx style="verb">maxConvertSize</spanx>.</t>
  <t>"conversionFailed" — the decompression failed entirely.</t>
</list></t>

</section>
<section anchor="deltarecipe"><name>DeltaRecipe</name>

<t>A DeltaRecipe computes a delta between two blobs.  It is an object
with the following properties:</t>

<t><list style="symbols">
  <t>blobId: "BlobId"
The blobId of the original (base) blob.</t>
  <t>newBlobId: "BlobId"
The blobId of the new blob to compare against.</t>
  <t>type: "String"
The media type of the delta format to produce.  <bcp14>MUST</bcp14> be one of the
values in the server's <spanx style="verb">supportedDeltaTypes</spanx> capability.</t>
</list></t>

<t>The result blob is the computed delta, which can be applied to the
base blob using PatchRecipe to reconstruct the new blob.</t>

<t>Errors:</t>

<t><list style="symbols">
  <t>"notFound" — a referenced blobId does not exist.</t>
  <t>"invalidProperties" — the type is not in <spanx style="verb">supportedDeltaTypes</spanx>.</t>
  <t>"tooLarge" — a referenced blob exceeds <spanx style="verb">maxConvertSize</spanx>.</t>
  <t>"conversionFailed" — the delta computation failed entirely.</t>
</list></t>

<section anchor="considerations-for-applicationx-rdiff-delta"><name>Considerations for application/x-rdiff-delta</name>

<t>The server computes an rdiff signature of the base blob and then
generates a delta against the new blob.  The resulting delta blob
can only be applied to the exact base blob used to generate it.</t>

</section>
<section anchor="considerations-for-applicationx-bsdiff"><name>Considerations for application/x-bsdiff</name>

<t>The server produces a bsdiff-format patch.  Both blobs must fit in
memory; servers <bcp14>MAY</bcp14> reject very large blobs with a "tooLarge" error.</t>

</section>
<section anchor="considerations-for-textx-diff"><name>Considerations for text/x-diff</name>

<t>The server produces a unified diff.  Both blobs are interpreted as
text.  If either blob contains content that cannot be interpreted as
text, the server <bcp14>MUST</bcp14> return an "unknownFormat" error.</t>

</section>
</section>
<section anchor="patchrecipe"><name>PatchRecipe</name>

<t>A PatchRecipe applies a delta to a base blob to produce a new blob.
It is an object with the following properties:</t>

<t><list style="symbols">
  <t>blobId: "BlobId"
The blobId of the base blob to patch.</t>
  <t>deltaBlobId: "BlobId"
The blobId of the delta to apply.</t>
  <t>deltaType: "String"
The media type of the delta format.  <bcp14>MUST</bcp14> be one of the values in
the server's <spanx style="verb">supportedPatchTypes</spanx> capability.</t>
</list></t>

<t>The result blob is the patched output.</t>

<t>Errors:</t>

<t><list style="symbols">
  <t>"notFound" — a referenced blobId does not exist.</t>
  <t>"unknownFormat" — the delta blob is not valid for the specified
format (e.g., corrupt or malformed delta data).</t>
  <t>"invalidProperties" — the deltaType is not in <spanx style="verb">supportedPatchTypes</spanx>.</t>
  <t>"tooLarge" — a referenced blob exceeds <spanx style="verb">maxConvertSize</spanx>.</t>
  <t>"conversionFailed" — the patch application failed entirely.</t>
</list></t>

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

<section anchor="uploading-a-blob-inline"><name>Uploading a Blob Inline</name>

<t>This example creates a blob from inline text data:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/set", {
  "accountId": "abc",
  "create": {
    "b1": {
      "data": [{"data:asText": "Hello, world!"}],
      "type": "text/plain"
    }
  }
}, "0"]]
]]></sourcecode></figure>

<t>The response:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/set", {
  "accountId": "abc",
  "created": {
    "b1": {
      "id": "Babc123",
      "type": "text/plain",
      "size": 13
    }
  },
  "notCreated": null
}, "0"]]
]]></sourcecode></figure>

</section>
<section anchor="querying-blob-chunks"><name>Querying Blob Chunks</name>

<t>This example fetches a blob's chunk structure with offsets, sizes,
and SHA-256 digests:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/get", {
  "accountId": "abc",
  "ids": ["B1a2b3c"],
  "properties": ["size", "chunks"],
  "dataSourceProperties": [
    "blobId", "size", "offset", "length", "position",
    "digest:sha-256"
  ]
}, "0"]]
]]></sourcecode></figure>

<t>The response shows the blob is stored as two chunks:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/get", {
  "accountId": "abc",
  "list": [{
    "id": "B1a2b3c",
    "size": 10485760,
    "chunks": [
      {
        "blobId": "Bchunk1",
        "size": 5242880,
        "offset": 0,
        "length": 5242880,
        "position": 0,
        "digest:sha-256": "a1b2c3..."
      },
      {
        "blobId": "Bchunk2",
        "size": 5242880,
        "offset": 0,
        "length": 5242880,
        "position": 5242880,
        "digest:sha-256": "d4e5f6..."
      }
    ]
  }],
  "notFound": []
}, "0"]]
]]></sourcecode></figure>

<t>The <spanx style="verb">position</spanx> values show where each chunk fits in the assembled
blob, and the <spanx style="verb">digest:sha-256</spanx> values can be used to verify chunk
integrity.</t>

</section>
<section anchor="looking-up-blob-references"><name>Looking Up Blob References</name>

<t>This example finds which Mailbox and Email objects reference two
blobs:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/lookup", {
  "accountId": "abc",
  "typeNames": ["Mailbox", "Email"],
  "ids": ["Bfirst", "Bsecond"]
}, "0"]]
]]></sourcecode></figure>

<t>The response shows that the first blob is referenced by two emails
in the same mailbox, and the second blob is not referenced by any
objects of the requested types (or is not visible to the user):</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/lookup", {
  "accountId": "abc",
  "list": [
    {
      "id": "Bfirst",
      "matchedIds": {
        "Mailbox": ["M1"],
        "Email": ["E1", "E2"]
      }
    },
    {
      "id": "Bsecond",
      "matchedIds": {
        "Mailbox": [],
        "Email": []
      }
    }
  ]
}, "0"]]
]]></sourcecode></figure>

</section>
<section anchor="creating-a-zip-archive"><name>Creating a Zip Archive</name>

<t>This example creates a zip file containing an HTML document, a CSS
file, and a JPEG image:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/convert", {
  "accountId": "abc",
  "create": {
    "z1": {
      "archive": {
        "type": "application/zip",
        "entries": [
          {
            "name": "site/index.html",
            "blobId": "Baaaa"
          },
          {
            "name": "site/style.css",
            "blobId": "Bbbbb"
          },
          {
            "name": "site/photo.jpg",
            "blobId": "Bcccc"
          }
        ]
      }
    }
  }
}, "0"]]
]]></sourcecode></figure>

<t>The response includes the blobId, type, and size of the created
archive:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/convert", {
  "accountId": "abc",
  "created": {
    "z1": {
      "id": "B9f2a4e",
      "type": "application/zip",
      "size": 104857
    }
  },
  "notCreated": {}
}, "0"]]
]]></sourcecode></figure>

</section>
<section anchor="creating-a-compressed-tar-archive"><name>Creating a Compressed Tar Archive</name>

<t>This example creates a .tar.gz file from the same three files.
The intermediate tar blob uses <spanx style="verb">noPersist</spanx> since only the final
compressed result is needed:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/convert", {
  "accountId": "abc",
  "create": {
    "t1": {
      "noPersist": true,
      "archive": {
        "type": "application/x-tar",
        "entries": [
          {
            "name": "site/index.html",
            "blobId": "Baaaa",
            "modified": "2026-03-01T12:00:00Z",
            "mode": "0644"
          },
          {
            "name": "site/style.css",
            "blobId": "Bbbbb",
            "modified": "2026-03-01T12:00:00Z",
            "mode": "0644"
          },
          {
            "name": "site/photo.jpg",
            "blobId": "Bcccc",
            "modified": "2026-02-15T09:30:00Z",
            "mode": "0644"
          }
        ]
      }
    },
    "t2": {
      "compress": {
        "blobId": "#t1",
        "type": "application/gzip"
      }
    }
  }
}, "0"]]
]]></sourcecode></figure>

<t>Because "t1" was created with <spanx style="verb">noPersist</spanx>, the server may omit it
from the response:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/convert", {
  "accountId": "abc",
  "created": {
    "t2": {
      "id": "Bd81c7f",
      "type": "application/gzip",
      "size": 98304
    }
  },
  "notCreated": {}
}, "0"]]
]]></sourcecode></figure>

</section>
<section anchor="extracting-a-compressed-tar-archive"><name>Extracting a Compressed Tar Archive</name>

<t>This example decompresses and extracts a .tar.gz file to discover
its contents.  The intermediate decompressed tar blob uses
<spanx style="verb">noPersist</spanx>:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/convert", {
  "accountId": "abc",
  "create": {
    "u1": {
      "noPersist": true,
      "decompress": {
        "blobId": "Bd81c7f",
        "type": "application/gzip"
      }
    },
    "u2": {
      "extract": {
        "blobId": "#u1",
        "type": "application/x-tar"
      }
    }
  }
}, "0"]]
]]></sourcecode></figure>

<t>The response for the ExtractRecipe includes the standard creation
response properties plus an <spanx style="verb">entries</spanx> array listing the archive
contents, with a blobId for each file entry:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/convert", {
  "accountId": "abc",
  "created": {
    "u2": {
      "id": "Be3a901",
      "type": "application/x-tar",
      "size": 102400,
      "entries": [
        {
          "name": "site/index.html",
          "blobId": "Bdd001",
          "entryType": "file",
          "modified": "2026-03-01T12:00:00Z",
          "mode": "0644"
        },
        {
          "name": "site/style.css",
          "blobId": "Bdd002",
          "entryType": "file",
          "modified": "2026-03-01T12:00:00Z",
          "mode": "0644"
        },
        {
          "name": "site/photo.jpg",
          "blobId": "Bdd003",
          "entryType": "file",
          "modified": "2026-02-15T09:30:00Z",
          "mode": "0644"
        }
      ]
    }
  },
  "notCreated": {}
}, "0"]]
]]></sourcecode></figure>

<t>The returned blobIds ("Bdd001", "Bdd002", "Bdd003") can be used
to download individual files or as inputs to further Blob/convert
operations.</t>

</section>
<section anchor="computing-and-applying-a-delta"><name>Computing and Applying a Delta</name>

<t>This example computes a unified diff between two versions of a
text file:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/convert", {
  "accountId": "abc",
  "create": {
    "d1": {
      "delta": {
        "blobId": "BoldVersion",
        "newBlobId": "BnewVersion",
        "type": "text/x-diff"
      }
    }
  }
}, "0"]]
]]></sourcecode></figure>

<t>The response contains the delta blob:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/convert", {
  "accountId": "abc",
  "created": {
    "d1": {
      "id": "Bdelta789",
      "type": "text/x-diff",
      "size": 1234
    }
  },
  "notCreated": {}
}, "0"]]
]]></sourcecode></figure>

<t>The delta can later be applied to the original blob to reconstruct
the new version:</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/convert", {
  "accountId": "abc",
  "create": {
    "p1": {
      "patch": {
        "blobId": "BoldVersion",
        "deltaBlobId": "Bdelta789",
        "deltaType": "text/x-diff"
      }
    }
  }
}, "0"]]
]]></sourcecode></figure>

<t>The result is a blob identical to "BnewVersion":</t>

<figure><sourcecode type="json"><![CDATA[
[["Blob/convert", {
  "accountId": "abc",
  "created": {
    "p1": {
      "id": "Breconstructed",
      "type": "application/octet-stream",
      "size": 48576
    }
  },
  "notCreated": {}
}, "0"]]
]]></sourcecode></figure>

</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="access-control"><name>Access Control</name>

<t>Servers <bcp14>MUST NOT</bcp14> allow a client to access blob data that the
authenticated user does not have permission to access.  When a
DataSourceObject references a blobId, the server <bcp14>MUST</bcp14> verify that the
requesting user has access to that blob.</t>

</section>
<section anchor="untrusted-data"><name>Untrusted Data</name>

<t>Clients that create blobs from inline data (data:asText or
data:asBase64) <bcp14>MUST NOT</bcp14> assume that the server will accept all
possible values.  Servers <bcp14>MUST</bcp14> reject malformed inputs as specified
in the DataSourceObject definition.</t>

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

<t>Several operations defined in this document can consume significant
server resources.</t>

<t>Archive and compression operations may require substantial CPU and
memory.  Servers <bcp14>SHOULD</bcp14> impose reasonable limits on archive size,
number of entries, nesting depth of archives within archives,
compression ratios (to mitigate zip bomb attacks), and total
processing time.  Servers <bcp14>SHOULD</bcp14> reject requests that would exceed
these limits with a "tooLarge" or "serverFail" error as appropriate.</t>

<t>Image conversion can also consume significant resources, especially
for very large images or high output dimensions.</t>

<t>Delta and patch operations can also be resource-intensive,
particularly for large blobs.  Servers <bcp14>SHOULD</bcp14> impose limits on the
size of blobs that can be used as inputs to these operations.</t>

<t>Servers <bcp14>SHOULD</bcp14> advertise their limits via the <spanx style="verb">maxConvertSize</spanx>,
<spanx style="verb">maxArchiveEntries</spanx>, and <spanx style="verb">maxImageDimension</spanx> capability properties
so that clients can avoid making requests that will be rejected.
Even when these properties are not advertised, servers <bcp14>SHOULD</bcp14> set
sensible internal limits and reject requests that exceed them.</t>

</section>
<section anchor="archive-path-traversal"><name>Archive Path Traversal</name>

<t>Archive formats allow entry names containing path separators and
relative path components such as "../".  Malicious archives may use
names like "../../etc/passwd" to attempt directory traversal.  While
ExtractRecipe only returns entry metadata and blob references
(not files on the server filesystem), clients that extract archive
contents to a filesystem <bcp14>MUST</bcp14> validate entry names and reject or
sanitize paths containing ".." components or absolute paths.
Servers <bcp14>SHOULD</bcp14> reject ArchiveRecipe requests containing entry names
with ".." path components.</t>

</section>
<section anchor="content-smuggling"><name>Content Smuggling</name>

<t>The ability to split content into multiple blobs, recombine them via
Blob/set, and apply delta patches may be used to bypass security
scanners that inspect blob content.  Servers that perform content
scanning <bcp14>SHOULD</bcp14> scan the output of Blob/convert operations as well
as the inputs.</t>

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

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

<t>IANA is requested to register the "Blob Management" Capability as follows:</t>

<t>Capability Name: urn:ietf:params:jmap:blob2</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="jmap-error-code-registrations"><name>JMAP Error Code Registrations</name>

<t>IANA is requested to register the following entries in the "JMAP
Error Codes" registry:</t>

<section anchor="unknowndatatype"><name>unknownDataType</name>

<t>JMAP Error Code: unknownDataType</t>

<t>Intended use: common</t>

<t>Change Controller: IETF</t>

<t>Description: The server does not recognise the data type specified
in the typeNames array of a Blob/lookup request, or the capability
required to use that data type has not been included in the <spanx style="verb">using</spanx>
array of the request.</t>

<t>Reference: this document</t>

</section>
<section anchor="unknownformat"><name>unknownFormat</name>

<t>JMAP Error Code: unknownFormat</t>

<t>Intended use: common</t>

<t>Change Controller: IETF</t>

<t>Description: The server could not determine the format of the blob,
or the detected format is not supported.  This error is returned
when auto-detection of archive or compression format fails, or when
the blob content does not match the specified format.</t>

<t>Reference: this document</t>

</section>
<section anchor="blobhasreference"><name>blobHasReference</name>

<t>JMAP Error Code: blobHasReference</t>

<t>Intended use: common</t>

<t>Change Controller: IETF</t>

<t>Description: The blob cannot be destroyed because it is still
referenced by one or more objects.  The client can use Blob/lookup
to discover which objects reference the blob.</t>

<t>Reference: this document</t>

</section>
<section anchor="conversionfailed"><name>conversionFailed</name>

<t>JMAP Error Code: conversionFailed</t>

<t>Intended use: common</t>

<t>Change Controller: IETF</t>

<t>Description: The server was unable to perform the requested blob
conversion.</t>

<t>Reference: this document</t>

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

<t>IANA is requested to update the reference for the "JMAP Data Types"
registry to this document (replacing the reference to RFC9404).</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-blobext/</t>

<t><strong>draft-ietf-jmap-blobext-02</strong></t>

<t><list style="symbols">
  <t>Listed <spanx style="verb">chunks</spanx> as a requestable Blob/get property and fixed the
chunks example to request it.</t>
  <t>Explained the purpose of the DataSourceObject <spanx style="verb">position</spanx> property.</t>
  <t>Servers that do not store blobs in chunks return a single chunk
covering the whole blob.</t>
  <t>Added a Blob/lookup example.</t>
  <t>Extended acknowledgements.</t>
</list></t>

<t><strong>draft-ietf-jmap-blobext-01</strong></t>

<t><list style="symbols">
  <t>Added per-account <spanx style="verb">uploadUrl</spanx> capability property, allowing
servers to direct uploads for individual accounts to a different
endpoint.  Uploads to this URL return an <spanx style="verb">expires</spanx> property in
addition to the standard upload response fields.</t>
  <t>Blob/set is now a standard Foo/set method with state strings
(ifInState/oldState/newState).  Renamed UploadObject to
BlobCreateObject.  The <spanx style="verb">expires</spanx> property can be set via update.</t>
  <t>Removed hardcoded type value lists from normative text (supportedArchiveTypes,
supportedCompressTypes, supportedDeltaTypes, ArchiveRecipe, CompressRecipe).
Values are now described as media types per <xref target="MEDIA-TYPES"/>.  Format-specific
considerations subsections remain as informative examples.</t>
  <t>Obsoletes RFC9404: incorporated all content from RFC9404 into
this document, making it self-contained.</t>
  <t>Renamed Blob/upload to Blob/set, making it a standard Foo/set
operation with create, update, and destroy at the top level.</t>
  <t>Added <spanx style="verb">urn:ietf:params:jmap:blob</spanx> capability definition (previously
defined only in RFC9404).</t>
  <t>Added Blob/lookup method (previously defined only in RFC9404).</t>
  <t>Added full DataSourceObject definition (merging RFC9404 base
definition with blobext extensions).</t>
  <t>Added full Blob/get definition (merging RFC9404 base definition
with blobext extensions).</t>
  <t>Added inline blob creation example.</t>
  <t>Updated IANA section to include blob capability, unknownDataType
error code, and JMAP Data Types registry.</t>
</list></t>

<t><strong>draft-ietf-jmap-blobext-00</strong></t>

<t><list style="symbols">
  <t>No changes, just uploading with the new name</t>
</list></t>

<t><strong>draft-gondwana-jmap-blobext-06</strong></t>

<t><list style="symbols">
  <t>Removed resumableUploadUrl capability property.</t>
  <t>Added isIncomplete and description response properties for
partial conversion results.</t>
  <t>Added conversionFailed error code for total conversion failure.</t>
  <t>Made expires always present (null if indeterminate) rather than
optional.</t>
  <t>Split supportedImageTypes into supportedImageReadTypes and
supportedImageWriteTypes.</t>
  <t>Made all supported type lists nullable (null = not supported).</t>
  <t>Changed imageData duration from UnsignedInt to Number for
sub-second precision.</t>
  <t>Clarified imageData comment as read-only.</t>
  <t>Added EXIF orientation reference and digest algorithm registry
reference.</t>
  <t>Fixed grammar and consistent error ordering across recipes.</t>
  <t>Structural reorder: DataSourceObject before Blob/get, ArchiveEntry
promoted to peer section.</t>
</list></t>

<t><strong>draft-gondwana-jmap-blobext-05</strong></t>

<t><list style="symbols">
  <t>Added imageData property to Blob/get for image/video metadata
extraction (dimensions, orientation, date, GPS, duration).</t>
  <t>Renamed UnArchiveRecipe to ExtractRecipe and UnCompressRecipe
to DecompressRecipe.</t>
  <t>Split capability lists into separate create/extract pairs:
supportedArchiveTypes/supportedExtractTypes,
supportedCompressTypes/supportedDecompressTypes,
supportedDeltaTypes/supportedPatchTypes.</t>
</list></t>

<t><strong>draft-gondwana-jmap-blobext-04</strong></t>

<t><list style="symbols">
  <t>Moved noPersist from top-level Blob/upload property to per-item
in the create map, for consistency with Blob/convert.</t>
</list></t>

<t><strong>draft-gondwana-jmap-blobext-03</strong></t>

<t><list style="symbols">
  <t>Added update (touch) and destroy operations to Blob/upload.</t>
</list></t>

<t><strong>draft-gondwana-jmap-blobext-02</strong></t>

<t><list style="symbols">
  <t>Replaced RdiffRecipe with generic DeltaRecipe and PatchRecipe using
media types (rdiff, bsdiff, unified diff).</t>
  <t>Replaced supportsRdiff with supportedPatchTypes capability.</t>
  <t>Clarified chunkSize as a hint, not a definitive statement.</t>
  <t>Added lazy generation text for Blob/convert (deferred output).</t>
  <t>Defined "expires" response property for blob creation responses.</t>
</list></t>

<t><strong>draft-gondwana-jmap-blobext-01</strong></t>

<t><list style="symbols">
  <t>Added Blob/convert method with recipes for image conversion, archiving,
compression, and rdiff.</t>
  <t>Added noPersist option to Blob/upload and Blob/convert for ephemeral
intermediate blobs in pipelines.</t>
  <t>Removed rdiffSignature and rdiffPatch from Blob/get and DataSourceObject.</t>
  <t>Fleshed out capability object with supported type lists.</t>
  <t>Added capability and method examples.</t>
  <t>Expanded Security Considerations.</t>
  <t>Updated IANA registrations with error codes and corrected capability URI.</t>
  <t>Added limit capability properties: maxConvertSize, maxArchiveEntries,
maxImageDimension, and supportsRdiff.</t>
  <t>Added dependency resolution requirement for Blob/convert create map
with cycle detection.</t>
  <t>Now updates both RFC 8620 and RFC 9404.</t>
</list></t>

<t><strong>draft-gondwana-jmap-blobext-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 Mauro De Gennaro, Ben Bucksch,
Ricardo Signes, Neil Jenkins, Ken Murchison, Arnt Gulbrandsen,
Seph Gentle, Matthew Horsfall, and the members of the JMAP Working Group at the
IETF for their contributions and feedback.</t>

<t>{backmatter}</t>

</section>


  </middle>

  <back>



    <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="MEDIA-TYPES">
  <front>
    <title>Media Type Specifications and Registration Procedures</title>
    <author fullname="N. Freed" initials="N." surname="Freed"/>
    <author fullname="J. Klensin" initials="J." surname="Klensin"/>
    <author fullname="T. Hansen" initials="T." surname="Hansen"/>
    <date month="January" year="2013"/>
    <abstract>
      <t>This document defines procedures for the specification and registration of media types for use in HTTP, MIME, and other Internet protocols. This memo documents an Internet Best Current Practice.</t>
    </abstract>
  </front>
  <seriesInfo name="BCP" value="13"/>
  <seriesInfo name="RFC" value="6838"/>
  <seriesInfo name="DOI" value="10.17487/RFC6838"/>
</reference>

<reference anchor="BASE64">
  <front>
    <title>The Base16, Base32, and Base64 Data Encodings</title>
    <author fullname="S. Josefsson" initials="S." surname="Josefsson"/>
    <date month="October" year="2006"/>
    <abstract>
      <t>This document describes the commonly used base 64, base 32, and base 16 encoding schemes. It also discusses the use of line-feeds in encoded data, use of padding in encoded data, use of non-alphabet characters in encoded data, use of different encoding alphabets, and canonical encodings. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="4648"/>
  <seriesInfo name="DOI" value="10.17487/RFC4648"/>
</reference>

<reference anchor="DIGEST-ALGORITHMS">
  <front>
    <title>Instance Digests in HTTP</title>
    <author fullname="J. Mogul" initials="J." surname="Mogul"/>
    <author fullname="A. Van Hoff" initials="A." surname="Van Hoff"/>
    <date month="January" year="2002"/>
    <abstract>
      <t>HTTP/1.1 defines a Content-MD5 header that allows a server to include a digest of the response body. However, this is specifically defined to cover the body of the actual message, not the contents of the full file (which might be quite different, if the response is a Content-Range, or uses a delta encoding). Also, the Content-MD5 is limited to one specific digest algorithm; other algorithms, such as SHA-1 (Secure Hash Standard), may be more appropriate in some circumstances. Finally, HTTP/1.1 provides no explicit mechanism by which a client may request a digest. This document proposes HTTP extensions that solve these problems. [STANDARDS-TRACK]</t>
    </abstract>
  </front>
  <seriesInfo name="RFC" value="3230"/>
  <seriesInfo name="DOI" value="10.17487/RFC3230"/>
</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>





  </back>

<!-- ##markdown-source:
H4sIAAAAAAAAA+V963LbVprgfzwFhvkRyUXKsuy4bWV2ZmVZdtTr21jy9PQk
riVIgCRiEODggJaYbKb2IfYB9ln2UfZJ9rueCwBSkuP0TNWmutoUCZzLd77z
3S+j0Shq8qbIjuM/vz55Fz8rqkn8OimTebbMyiZKJpM6++z9GKXVtEyW8Hxa
J7NmlGfNbPTzMlmNJvBrdt2MDo8is54sc2PyqrzcrODR87PLF9E0abJ5VW+O
Y9Ok0XqVwt/mOH7y+OgwqiamKjL6++mjw0dRvqqP46Zem+bo8PApjPgp21xV
dQpDlU1Wl1kzeo7TR6ZJyvS/J0VVwjSbzESr/Dj+sammw9hUdVNnMwOfNkv8
8DGKknWzqOrjKB5FMfyXlzDhs4P4ZVWmV7Bp+pJ396yuyvD7qp4fxy8S0yyT
vKBvMvx0HE/g0fl/nckvTZYsD6bVMorKql4mTf45O6anEYSj07fvz47j9y9O
adv49euz5+cno8u/vju7oB8eP3n4hH54dnJx9vgRfffo8SP+7vn5y7OLy9HJ
q5dv359f/vCaX3l49PAwiqK8nLkZo9FoFCcT09TJtImiy0UW//ni7Zv4ddYk
8clqVeRwHnBA8bu6AnBVRbyHC9yPJ4nJ4pX98tdf7bp/+20/gh8+52lm4gYG
TCZ5kTebuKni9aqokjSGw4jT6qrkP+pJDtPXm3iSl/gPnHgSf86T+IfLy3fR
u7cXl/TCy7PLGBaSxGk2y8ssjbMyXVV52RzE8eUiN8Hr8Oc0KQp4KokHiHKD
A9wdfA24l5WIc3GSpgb/L8cNJkV8lWwMLnJaZ4BzNGcynWYGRoYB4P838TL5
lJdzAGEBK4iXGaBJShOZ+CpvFjkuj3AtqVO+DHX2b+vM4BrPmzgpTCXTwg+f
s9pkUVFVn9YrGGu6SMrcLHEFaW6mFfwcXy2yOpPpE/gE+AlflFPYl8xXAYRr
2nPUwCVCNF6vVoDTMZxyXCT1XN9HiE4X6/ITvDytSjjy9ZSOFkeKTVbDhCMD
pxZVqyaHi0kHPyQ4eL/SaDgALh9fr1ZZTY8auCjTYp0ChOJ8CaQhYkTzHobR
6ukCMI+BTKcAw8OZIP7RA3AnVnVmjPwWpZn3Da8mzYomub9KmunCm/2AkXmZ
p2mRRdE3SAPqKuVNRtFFBceVLwEn6VxaGAtLB4LBazB0aHmti4TtJLxrnBzg
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

-->

</rfc>

