<?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-01" 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="April" day="21"/>

    
    
    <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.</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.  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>
</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'/>
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'/>
This property <bcp14>MUST</bcp14> be explicitly requested in <spanx style="verb">properties</spanx>.</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"],
  "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="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-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, 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+V923LcVpLgO74CU34wqaiiKEpWS3Rvz1KUZLPDuoxI9WVs
xRJVOFUFCwXU4KBE0R537EfsB+y37Kfsl2xezwVA8SJLMxOxjo5WsQo4lzx5
zzyZk8kkaYu2NIfpn18cvU6flPU0fZFV2cKsTNUm2XTamA/Bj0lez6psBc/n
TTZvJ4Vp55OfV9l6MoVfzcd2sn8vsZvpqrC2qKuzyzU8evLs7Hkyy1qzqJvL
w9S2ebJZ5/C3PUwfPTzYT+qprUtDfz9+sP8gKdbNYdo2G9se7O8/3j9I3pvL
i7rJYaiqNU1l2slTnD6xbVbl/yMr6wqmuTQ2WReH6Y9tPRuntm7axswtfLpc
4Yd3SZJt2mXdHCbpJEnhv6KCCZ/spd/VVX4Bm6YveXdPmrqKv6+bxWH6PLPt
KitK+sbgp8N0Co8u/vtcfmlNttqb1askqepmlbXFB3NITyMIJ8ev3jw7TN88
P6Zt49cvnj09OZqc/f31s1P64eGj+4/ohydHp88ePqDvHjx8wN89Pfnu2enZ
5OiH7169OTn7/gW/cv/g/n6SJEU19zMmk8kkzaa2bbJZmyRnS5P++fTVy/SF
abP0aL0uCzgPOKD0dVMDuOoy3cEF7qbTzJp07b789Ve37t9+203ghw9Fbmza
woDZtCiL9jJt63SzLussT+Ew0ry+qPiPZlrA9M1lOi0q/AdOPEs/FFn6/dnZ
6+T1q9MzeuG7Z2cpLCRLczMvKpOnpsrXdVG1e2l6tixs9Dr8OcvKEp7K0hGi
3GgPdwdfA+6ZCnEuzfLc4v8VuMGsTC+yS4uLnDUGcI7mzGYzY2FkGAD+/zJd
Ze+LagEgLGEF6coAmuQ0kU0vinZZ4PII17ImZ2JozL9tjMU1nrRpVtpapoUf
PpjGmqSs6/ebNYw1W2ZVYVe4grywsxp+Ti+WpjEyfQafAD/hi2oG+5L5aoBw
Q3tOWiAiROPNeg04ncIpp2XWLPR9hOhsuanew8uzuoIj38zoaHGk1JoGJpxY
OLWkXrcFECYd/JjgEPxKo+EAuHx8vV6bhh61QCizcpMDhNJiBawhYUQLHobR
mtkSMI+BTKcAw8OZIP7RA0AT68ZYK78luQm+4dXkpmyzu+usnS2D2fcYmVdF
npcmSb5CHtDUOW8ySU5rOK5iBThJ59LBWFg6MAxeg6VDKxpdJGwn413j5ADv
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
joWbYd+/4r8rjFc2vyX/D+F8mS743QAA

-->

</rfc>

