XEP-0136: Message Archiving

This document defines mechanisms and preferences for the archiving and retrieval of XMPP messages.


WARNING: This Standards-Track document is Experimental. Publication as an XMPP Extension Protocol does not imply approval of this proposal by the XMPP Standards Foundation. Implementation of the protocol described herein is encouraged in exploratory implementations, but production systems should not deploy implementations of this protocol until it advances to a status of Draft.


Document Information

Series: XEP
Number: 0136
Publisher: XMPP Standards Foundation
Status: Experimental
Type: Standards Track
Version: 0.14
Last Updated: 2007-08-16
Approving Body: XMPP Council
Dependencies: XMPP Core, XMPP IM, XEP-0004, XEP-0030, XEP-0059, XEP-0060, XEP-0155, XEP-0163, W3C XML Encryption, W3C XML Signature
Supersedes: None
Superseded By: None
Short Name: archive
Wiki Page: <http://wiki.jabber.org/index.php/Message Archiving (XEP-0136)>


Author Information

Ian Paterson

Email: ian.paterson@clientside.co.uk
JabberID: ian@zoofy.com

Jon Perlow

Email: jonp@google.com
JabberID: jonp@google.com

Peter Saint-Andre

JabberID: stpeter@jabber.org
URI: https://stpeter.im/

Justin Karneges

Email: justin@affinix.com
JabberID: justin@andbit.net


Legal Notices

Copyright

This XMPP Extension Protocol is copyright (c) 1999 - 2008 by the XMPP Standards Foundation (XSF).

Permissions

Permission is hereby granted, free of charge, to any person obtaining a copy of this specification (the "Specification"), to make use of the Specification without restriction, including without limitation the rights to implement the Specification in a software program, deploy the Specification in a network service, and copy, modify, merge, publish, translate, distribute, sublicense, or sell copies of the Specification, and to permit persons to whom the Specification is furnished to do so, subject to the condition that the foregoing copyright notice and this permission notice shall be included in all copies or substantial portions of the Specification. Unless separate permission is granted, modified works that are redistributed shall not contain misleading information regarding the authors, title, number, or publisher of the Specification, and shall not claim endorsement of the modified works by the authors, any organization or project to which the authors belong, or the XMPP Standards Foundation.

Disclaimer of Warranty

## NOTE WELL: This Specification is provided on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. In no event shall the XMPP Standards Foundation or the authors of this Specification be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the Specification or the implementation, deployment, or other use of the Specification. ##

Limitation of Liability

In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall the XMPP Standards Foundation or any author of this Specification be liable for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising out of the use or inability to use the Specification (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if the XMPP Standards Foundation or such author has been advised of the possibility of such damages.

IPR Conformance

This XMPP Extension Protocol has been contributed in full conformance with the XSF's Intellectual Property Rights Policy (a copy of which may be found at <http://www.xmpp.org/extensions/ipr-policy.shtml> or obtained by writing to XSF, P.O. Box 1641, Denver, CO 80201 USA).

Discussion Venue

The preferred venue for discussion of this document is the Standards discussion list: <http://mail.jabber.org/mailman/listinfo/standards>.

Errata may be sent to <editor@xmpp.org>.

Relation to XMPP

The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 3920) and XMPP IM (RFC 3921) specifications contributed by the XMPP Standards Foundation to the Internet Standards Process, which is managed by the Internet Engineering Task Force in accordance with RFC 2026. Any protocol defined in this document has been developed outside the Internet Standards Process and is to be understood as an extension to XMPP rather than as an evolution, development, or modification of XMPP itself.

Conformance Terms

The following keywords as used in this document are to be interpreted as described in RFC 2119: "MUST", "SHALL", "REQUIRED"; "MUST NOT", "SHALL NOT"; "SHOULD", "RECOMMENDED"; "SHOULD NOT", "NOT RECOMMENDED"; "MAY", "OPTIONAL".


Table of Contents


1. Introduction
2. Determining Server Support
3. Archiving Preferences
    3.1. Introduction
    3.2. Preference Syntax
       3.2.1. Auto Element
       3.2.2. Default Element
         3.2.2.1. expire Attribute
         3.2.2.2. otr Attribute
         3.2.2.3. save Attribute
       3.2.3. Item Element
         3.2.3.1. expire Attribute
         3.2.3.2. jid Attribute
         3.2.3.3. otr Attribute
         3.2.3.4. save Attribute
       3.2.4. Method Element
         3.2.4.1. type Attribute
         3.2.4.2. use Attribute
    3.3. Determining Preferences
    3.4. Setting Default Modes
    3.5. Setting Modes for a Contact
    3.6. Setting Archiving Method Preferences
4. Off The Record
    4.1. OTR Negotiation
    4.2. Notes
5. Manual Archiving
    5.1. Introduction
    5.2. Collections
    5.3. Uploading Messages to a Collection
    5.4. Changing the Subject of a Collection
    5.5. Offline Messages
    5.6. Groupchat Messages
    5.7. Linking Collections
    5.8. Associating Attributes with a Collection
6. Encryption
7. Automated Archiving
    7.1. Toggling Auto-Archiving
    7.2. Enabling Auto-Archiving with Encryption
    7.3. Not-Implemented Responses
8. Archive Management
    8.1. Retrieving a List of Collections
    8.2. Retrieving a Collection
    8.3. Removing a Collection
9. Replacing EncryptedKey Elements
10. Replication
11. File Format
12. Implementation Notes
    12.1. Time Synchronization
    12.2. Bandwidth Considerations
    12.3. Storage Considerations
13. Stream Feature
14. Security Considerations
    14.1. Automatic Archiving Defaulting to On
    14.2. Plain Text Subject
    14.3. Store Headers
15. IANA Considerations
16. XMPP Registrar Considerations
    16.1. Protocol Namespace
    16.2. Service Discovery Features
    16.3. Field Standardization
17. XML Schemas
Notes
Revision History


1. Introduction

Many XMPP clients implement some form of client-side message archiving. However, it is not always convenient or even possible to archive messages locally, e.g., because it is easier to keep all archives in one universally accessible place (not scattered around on multiple computers or devices) or because the client operates in a web browser or resides on a mobile device that does not have sufficient local storage for message archiving. In addition, server-side archiving makes it possible to offer new services such as integration of IM and email. Therefore it is beneficial to define methods for server-side archiving of XMPP messages.

There are two main approaches to this problem:

  1. Enable the client to send individual messages or entire conversations to the server for archiving (optionally after encryption); we call this manual archiving.
  2. Enable the server (at the client's request) to archive messages as they pass through the server; we call this automated archiving.

So that client and server developers can refer to one specification, both approaches are defined in this document. In addition, this document defines common methods for retrieving and managing archived messages.

Complying with XMPP Core, the server MUST respond to all <iq/> element of type 'get' or 'set'. However, most successful responses have been omitted from this document in the interest of conciseness.

2. Determining Server Support

A client discovers whether its server supports this protocol using Service Discovery [1].

Example 1. Client Service Discovery request

    
<iq type='get' id='disco1'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>

For each feature defined herein, if the server supports that feature it MUST return a <feature/> element with the 'var' attribute set to 'http://www.xmpp.org/extensions/xep-0136.html#ns-name' (see Protocol Namespaces regarding issuance of one or more permanent namespaces), where 'name' is 'auto' for the Automated Archiving feature, 'encrypt' for the server-side encryption feature (see Automated Archiving), 'manage' for the Archive Management feature, 'manual' for the Manual Archiving feature, and 'pref' for the Archiving Preferences feature.

Example 2. Server Service Discovery response

    
<iq type='result' to='romeo@montague.net/orchard' id='disco1'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
    ...
    <feature var='http://www.xmpp.org/extensions/xep-0136.html#ns-auto'/>
    <feature var='http://www.xmpp.org/extensions/xep-0136.html#ns-encrypt'/>
    <feature var='http://www.xmpp.org/extensions/xep-0136.html#ns-manage'/>
    <feature var='http://www.xmpp.org/extensions/xep-0136.html#ns-manual'/>
    <feature var='http://www.xmpp.org/extensions/xep-0136.html#ns-pref'/>
    ...
  </query>
</iq>

3. Archiving Preferences

3.1 Introduction

Not all users want to archive messages. A client SHOULD save its user's default archiving preference (or "Save Mode") to its own server (i.e., specify whether by default all conversations should be archived or not). In addition, a client MAY save different preferences for particular contacts.

Some users may also prefer that the messages they exchange with contacts are "Off The Record" (OTR). [2] A client SHOULD save its user's default and contact-specific OTR preferences (or "OTR Modes") to its own server.

Whichever archiving method a client uses (e.g., local archiving to files or a database, or server-side archiving that happens either automatically or manually), it SHOULD adhere to its user's archiving preferences. However, a client MAY maintain a set of preferences in a local file which takes precedence over the preferences stored on the server for both local archiving and server-side archiving.

This section addresses the following use cases:

  1. A client determines its user's current default Save Mode and OTR Mode, and the Modes for particular contacts.
  2. A client sets the default Save Mode and OTR Mode.
  3. A client sets the Save Mode and OTR Mode for a particular contact.

3.2 Preference Syntax

Archiving preferences are encapsulated in four children of the <pref/> element: <auto/>, <default/>, <item/>, and <method/>. These are defined in the following sections.

3.2.1 Auto Element

The <auto/> element specifies the current Automated Archiving settings for this stream.

This element MUST be empty and MUST include a boolean 'save' attribute [3] that specifies whether automated archiving is enabled or disabled for this stream.

3.2.2 Default Element

The <default/> element specifies the default settings for both OTR Mode and Save Mode. The element MUST be empty and MUST include an 'otr' attribute and a 'save' attribute. The element MAY include an 'expire' attribute.

3.2.2.1 expire Attribute

If the 'save' attribute is not set to 'false' then is RECOMMENDED to also include an 'expire' attribute, which indicates how many seconds after messages are archived that the server SHOULD delete them.

3.2.2.2 otr Attribute

The 'otr' attribute specifies the user's default setting for OTR Mode. The allowable values are:

  • approve -- the user MUST explicitly approve off-the-record communication.
  • concede -- communications MAY be off the record if requested by another user.
  • forbid -- communications MUST NOT be off the record.
  • oppose -- communications SHOULD NOT be off the record even if requested.
  • prefer -- communications SHOULD be off the record if possible.
  • require -- communications MUST be off the record. *

* Note: If the OTR Mode is 'require' then the Save Mode MUST be 'false'. An 'otr' attribute value of "require" in Message Archiving is equivalent to a 'logging' attribute value of "mustnot" in Stanza Session Negotiation; for details, see the OTR Negotiation section of this document.

3.2.2.3 save Attribute

The 'save' attribute specifies the user's default setting for Save Mode. The allowable values are:

  • body -- the saving entity SHOULD save only <body/> elements. *
  • false -- the saving entity MUST save nothing.
  • message -- the saving entity SHOULD save the full XML content of each <message/> element. **
  • stream -- the saving entity SHOULD save every byte that passes over the stream in either direction. ***

* Note: When archiving locally a client MAY save the full XML content of each <message/> element even if the Save Mode is 'body'.

** Note: Support for the 'message' value is optional and, to conserve bandwidth and storage space, it is RECOMMENDED that client implementations do not specify the 'message' value. [4]

*** Note: The upload, retrieval and management of 'stream' archives is currently beyond the scope of this document.

3.2.3 Item Element

The <item/> element specifies the settings for both the OTR Mode and Save Mode with regard to a particular entity. The element MUST be empty and MUST include a 'jid' attribute, an 'otr' attribute, and a 'save' attribute. The element MAY include an 'expire' attribute.

3.2.3.1 expire Attribute

If the 'save' attribute is not set to 'false' then is RECOMMENDED to also include an 'expire' attribute, which indicates how many seconds after messages are archived that the server SHOULD delete them.

3.2.3.2 jid Attribute

The 'jid' attribute specifies the JabberID of the XMPP entity to which the preferences specified in this <item/> element apply.

3.2.3.3 otr Attribute

The 'otr' attribute specifies the user's setting for OTR Mode with regard to the specified JID. The allowable values are:

  • approve -- the user MUST explicitly approve off-the-record communication.
  • concede -- communications MAY be off the record if requested by another user.
  • forbid -- communications MUST NOT be off the record.
  • oppose -- communications SHOULD NOT be off the record even if requested.
  • prefer -- communications SHOULD be off the record if possible.
  • require -- communications MUST be off the record. *

* Note: If the OTR Mode is 'require' then the Save Mode MUST be 'false'. An 'otr' attribute value of "require" in Message Archiving is equivalent to a 'logging' attribute value of "mustnot" in Stanza Session Negotiation; for details, see the OTR Negotiation section of this document.

3.2.3.4 save Attribute

The 'save' attribute specifies the user's setting for Save Mode with regard to the specified JID. The allowable values are:

  • body -- the saving entity SHOULD save only <body/> elements.
  • false -- the saving entity MUST save nothing.
  • message -- the saving entity SHOULD save the full XML content of each <message/> element.
  • stream -- the saving entity SHOULD save every byte that passes over the stream in either direction. *

* Note: The upload, retrieval and management of 'stream' archives is currently beyond the scope of this document.

3.2.4 Method Element

Each <method/> element specifies the the user's preferences for one available archiving method. The <method/> element MUST be empty and MUST include both the 'type' and 'use' attributes. The <pref/> element MUST include at least three <method/> elements, differentiated by the value of the 'type' attribute.

3.2.4.1 type Attribute

The allowable values of the 'type' attribute are:

  • auto -- preferences for use of automatic archiving on the user's server.
  • local -- preferences for use of local archiving to a file or database on the user's machine or device.
  • manual -- preferences for use of manual archiving by the user's client to the user's server.

3.2.4.2 use Attribute

The allowable values of the 'use' attribute are:

  • concede -- this method MAY be used if no other methods are available.
  • forbid -- this method MUST NOT be used.
  • prefer -- this method SHOULD be used if available.

3.3 Determining Preferences

In order to determine its user's current Save Mode(s) and OTR Mode(s), a client sends to its server an IQ-get containing an empty <pref/> element qualified by the 'http://www.xmpp.org/extensions/xep-0136.html#ns' namespace (see Protocol Namespaces regarding issuance of one or more permanent namespaces).

Example 3. Client Requests Archiving Preferences

<iq type='get' id='pref1'>
  <pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'/>
</iq>
    

The server responds with the default Save Mode and OTR Mode (a single <default/> element) and any specific Save Modes and OTR Modes for individual contacts (zero or more <item/> elements).

Example 4. Server Returns Preferences

<iq type='result' id='pref1' to='juliet@capulet.com/chamber'>
  <pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <default save='body' otr='concede' expire='31536000'/>
    <item jid='romeo@montague.net' save='false' otr='require'/>
    <item jid='benvolio@montague.net' save='message' expire='630720000' otr='forbid'/>
    <method type='auto' use='forbid'/>
    <method type='local' use='concede'/>
    <method type='manual' use='prefer'/>
    <auto save='false'/>
  </pref>
</iq>
    

The foregoing preferences can be explained as follows:

  1. By default, message bodies should be saved (according the preferred method specified later), communications may be off the record if requested, and any saved messages should be expired after 1 year.
  2. When communicating with romeo@montague.net, both entities must not save messages and all communications must be off the record.
  3. When communicating with benvolio@montague.net, both entities should save full messages, communications must not be off the record, and any saved messages should be expired after 20 years.
  4. Server-side archiving must not occur automatically.
  5. Local archiving may be used if requested.
  6. Manual server-side archiving is preferred.

If the user has never set the default Modes, the 'save' and 'otr' attributes SHOULD specify the server's default settings, and the 'unset' attribute SHOULD be set to 'true'. Note: The 'unset' attribute defaults to 'false'.

Example 5. Server Returns Service Default Preferences

<iq type='result' id='pref1' to='juliet@capulet.com/chamber'>
  <pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <default save='false' otr='concede' unset='true'/>
    <method type='auto' use='concede'/>
    <method type='local' use='concede'/>
    <method type='manual' use='concede'/>
    <auto save='false'/>
  </pref>
</iq>
    

Once it has received a request for archiving preferences from the client, the server MUST send any subsequent changes to any of the user's archiving preferences to the client until the stream is closed (see below). Note: changes to the <auto/> element MUST NOT be replicated in this way.

3.4 Setting Default Modes

A client may set the default Modes:

Example 6. Client Sets Default Modes

<iq type='set' id='pref2'>
  <pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <default save='false' otr='prefer'/>
  </pref>
</iq>
    

If the server can process the request, it acknowledges the change:

Example 7. Server Acknowledges Change

<iq type='result' id='pref2' to='juliet@capulet.com/chamber'/>
    

The server then MUST inform all of the user's connected resources that have previously requested the user's archiving preferences:

Example 8. Server Pushes New Modes

<iq type='set' id='push1' to='juliet@capulet.com/chamber'>
  <pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <default save='false' otr='prefer'/>
  </pref>
</iq>

<iq type='set' id='push2' to='juliet@capulet.com/pda'>
  <pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <default save='false' otr='prefer'/>
  </pref>
</iq>
    

The server MAY be configured to return a <feature-not-implemented/> error in the following cases:

3.5 Setting Modes for a Contact

A client may use a similar protocol to set the Modes for a particular contact or domain of contacts (bare JID, full JID or domain). Note: It is STRONGLY RECOMMENDED for the value of the 'jid' attribute to be a bare JID (<node@domain.tld>).

Example 9. Client Sets Modes for a Contact

<iq type='set' id='pref3'>
  <pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <item jid='romeo@montague.net' save='body' expire='604800' otr='concede'/>
  </pref>
</iq>
    

Example 10. Server Acknowleges Change

<iq type='result' id='pref3' to='juliet@capulet.com/chamber'/>
    

Example 11. Server Pushes New Modes

<iq type='set' id='push3' to='juliet@capulet.com/chamber'>
  <pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <item jid='romeo@montague.net' save='body' expire='604800' otr='concede'/>
  </pref>
</iq>

<iq type='set' id='push4' to='juliet@capulet.com/pda'>
  <pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <item jid='romeo@montague.net' save='body' expire='604800' otr='concede'/>
  </pref>
</iq>
    

The same error cases apply as when Setting Default Modes.

3.6 Setting Archiving Method Preferences

Example 12. Client Sets Method Preferences

<iq type='set' id='pref4'>
  <pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <method type='auto' use='concede'/>
    <method type='local' use='forbid'/>
    <method type='manual' use='prefer'/>
  </pref>
</iq>
    

Example 13. Server Acknowleges Change

<iq type='result' id='pref4' to='juliet@capulet.com/chamber'/>
    

Example 14. Server Pushes New Method Preferences

<iq type='set' id='push5' to='juliet@capulet.com/chamber'>
  <pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <method type='auto' use='concede'/>
    <method type='local' use='forbid'/>
    <method type='manual' use='prefer'/>
  </pref>
</iq>

<iq type='set' id='push6' to='juliet@capulet.com/pda'>
  <pref xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <method type='auto' use='concede'/>
    <method type='local' use='forbid'/>
    <method type='manual' use='prefer'/>
  </pref>
</iq>
    

4. Off The Record

A user will sometimes exchange messages with contacts who prefer that their conversations are not archived by either party.

4.1 OTR Negotiation

Any client that archives messages SHOULD support Stanza Session Negotiation and its 'logging' field both to give other contacts the opportunity to indicate this preference, and to negotiate an "Off The Record" (OTR) policy that complies with its user's own Archiving Preferences.

Note: A client MUST NOT propose or agree to enable OTR (i.e., disallow message logging) unless it has confirmed that its server will allow it to switch off Automated Archiving.

Both parties to a stanza session negotiation may have OTR preferences (i.e, the initiating party or "user" and the responding party or "contact"). These preferences will interact in the ways specified below, resulting either in a successful negotiation or an unsuccessful negotiation (naturally, an unsuccessful negotiation can lead to a subsequent negotiation attempt by the user or the contact).

The following table shows what stanza session negotiation values the initating party (i.e., the "user") should send for the 'logging' field in the initial data form for a stanza session negotiation (note: 'may' means that the receiving party MAY enable message logging and 'mustnot' means that the receiving party MUST NOT enable logging).

Table 1: Stanza Session Negotiation logging options offered by initiating party (user)

User's OTR Preference Offering 'logging' Negotiation Option(s)*
require mustnot**
prefer mustnot,may
approve mustnot,may
concede may,mustnot***
oppose may,mustnot***
forbid may***

* In order of preference, the first value is the default.

** If the user receives no response it MUST NOT send any messages to the contact.

*** Alternatively, the user MAY decide not to initiate an OTR negotiation and to save messages (until the contact initiates a negotiation).

Note: When negotiating a stanza session, the user MUST include the <required/> element inside the 'logging' <field/> element. If the user does not receive a successful response to its chat negotiation request (and if the OTR Mode is not 'require'), then it SHOULD proceed as if the contact had responded with the value of the 'logging' <field/> element set to 'may'.

The following table shows what stanza session negotiation values the responding party (i.e., "contact") should send for the 'logging' field in its response to a stanza session negotiation request from the user.

Table 2: Stanza Session Negotiation logging value selected by responding party (contact)

Contact's OTR Preference Responding 'logging' Negotiation Values*
Initiator Options --> mustnot mustnot,may* may,mustnot* may
require OTR mode mustnot mustnot mustnot fail**
prefer OTR mode mustnot mustnot mustnot may
approve OTR mode mustnot mustnot may may
concede OTR mode mustnot mustnot may may
oppose OTR mode mustnot may may may
forbid OTR mode fail** may may may

* The first value is the default.

** The negotiation fails and the parties MUST NOT exchange any messages; however, the recipient MAY attempt to initiate a stanza session negotiation with the other party.

Note: If a contact does not include a 'logging' field in its initial Stanza Session Negotiation request, and a user's Archiving Preferences indicate that OTR is required, then the client MUST refuse the request. It MAY then send its own Stanza Session Negotiation request with a 'logging' field.

If a user's OTR preference for a contact changes during a Chat Session that has been negotiated with the contact, and if the new preference would affect the value of the 'logging' field that was previously negotiated, then the client MUST immediately renegotiate the 'logging' field according to the user's new OTR preference (or terminate the Chat Session).

4.2 Notes

If a Stanza Session Negotiation agreed to enable OTR then the clients MUST NOT allow messages sent in either direction to be archived in any way (including Manual Archiving and Automated Archiving). [5]

If a Stanza Session Negotiation agreed to enable OTR then both clients MUST ensure that the Stanza Session Negotiation messages themselves are not archived. For example, if Automated Archiving was enabled when the client received the initial Stanza Session Negotiation request, then the client MUST immediately ask its server to delete its copy of the request (see Removing a Collection for a description of how to remove the messages currently being recorded by the server).

5. Manual Archiving

5.1 Introduction

While automated archiving is easy for the client and server to implement, there are many contexts in which manual archiving is required. For examples, when:

Therefore, often a client will want to send or receive a sequence of messages, optionally add private notes to the sequence, optionally encrypt the sequence, and then ask the server to archive it. Such messages and notes SHOULD be stored on the server in the form of a "collection".

5.2 Collections

A "collection" is a set of messages to/from the same user that are received near each other in time or as part of the same conversation thread. A collection is intended to mimic the natural flow of human conversations, which in instant messaging (IM) systems tend to occur in bursts (e.g., a five-minute conversation one day, followed by a ten-minute conversation the next).

Each collection of messages and notes is encapsulated in a <chat/> element.

The client uniquely specifies a collection using a pair of attributes:

A friendly name for the collection MAY be specified with a 'subject' attribute. Note the Security Considerations regarding the subject attribute.

If an opaque thread ID (found in the <thread/> children of the <message/> elements whose content is stored in the collection) is associated with the conversation then it MUST be specified with a 'thread' attribute. Clients SHOULD include a <thread/> child in each <message/> element they send that is part of a conversation they expect will be archived (see Best Practices for Message Threads [8]).

Note: The content of <message/> elements that have different thread IDs SHOULD be archived in separate collections. The content of <message/> elements that have the same thread IDs SHOULD be archived in the same collection. The thread attribute SHOULD NOT be set to any value other than the exact content of the <thread/> elements. If no <thread/> elements appeared in the conversation the <chat/> element SHOULD have no thread attribute. Implementations SHOULD use the thread attribute for cross-referencing purposes only, within the archive each collection MUST be uniquely identified by the combination of its 'with' and 'start' attributes.

Each collection MAY contain <note/>, <to/> or <from/> elements (or <EncryptedData/> and <EncryptedKey/> elements - see Encryption).

The text of each individual private note MUST be encapsulated in a <note/> element. The absolute time the note was created SHOULD be specified with a 'utc' attribute (which MUST be UTC and adhere to the DateTime format specified in XEP-0082).

The content of each individual message MUST be encapsulated in a <to/> or <from/> element. The time in whole seconds of the message relative to the previous message in the collection (or, for the first message, relative to the start of the collection) SHOULD be specified with a 'secs' attribute. Note: When deciding whether to round up or down to a number of whole seconds, entities MUST ensure that the sum of the 'secs' attribute and the 'secs' attributes of the preceeding messages will accurately reflect the absolute time of the message. (e.g., if a sequence of messages occur at exactly 0.51-second intervals then the 'secs' attributes should generally alternate between '0' or '1'.)

The content of each <to/> or <from/> element SHOULD depend on the user's Archiving Preferences. <to/> or <from/> elements MUST NOT be empty. Note: A server MAY be configured to return a <feature-not-implemented/> error if any <to/> or <from/> element contains anything other than <body/> elements.

5.3 Uploading Messages to a Collection

A collection of messages and notes is uploaded to the server encapsulated in a <save/> element.

Example 15. Storing messages in a collection

<iq type='set' id='up1'>
  <save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='juliet@capulet.com/chamber'
          start='1469-07-21T02:56:15Z'
          thread='damduoeg08'
          subject='She speaks!'>
      <from secs='0'><body>Art thou not Romeo, and a Montague?</body></from>
      <to secs='11'><body>Neither, fair saint, if either thee dislike.</body></to>
      <from secs='7'><body>How cam'st thou hither, tell me, and wherefore?</body></from>
      <note utc='1469-07-21T03:04:35Z'>I think she might fancy me.</note>
    </chat>
  </save>
</iq>
    

If the collection does not exist then the server MUST create a new collection. If the collection already exists then the server MUST append the messages to the existing collection.

Note: Clients MUST take care to append each sequence of messages to the collection before the sequence becomes so large that uploading it may violate common rate limiting restrictions (in Jabber systems, often called "karma").

Example 16. Successful reply

<iq type='result' to='romeo@montague.net/orchard' id='up1'/>
    

If the server cannot service an upload request because the collection is too large then it MUST return a <not-acceptable/> error:

Example 17. Unsuccessful reply

<iq type='error' to='romeo@montague.net/orchard' id='up1'>
  <error code='406' type='modify'>
    <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>
    

5.4 Changing the Subject of a Collection

If the client specifies a new value for the 'subject' attribute of any existing collection then the server MUST update the existing value. Note: The client cannot specify new values for the 'with' or 'start' attributes. The only way to change these values is to delete the collection (see Removing a Collection) and then create a new one.

Example 18. Changing the subject of a collection without appending messages

<iq type='set' id='subject1'>
  <save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='juliet@capulet.com/chamber'
          start='1469-07-21T02:56:15Z'
          subject='She speaks twice!'/>
  </save>
</iq>
    

5.5 Offline Messages

The client MAY specify an absolute time for any message by providing a longer 'utc' attribute (which MUST be UTC and adhere to the DateTime format specified in XEP-0082) instead of a 'secs' attribute. The absolute time MAY be before the start time of the collection:

Example 19. Storing offline messages in a collection

<iq type='set' id='up2'>
  <save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='juliet@capulet.com/chamber'
          start='1469-07-21T02:56:15Z'
          subject='She speaks!'>
      <from utc='1469-07-21T00:32:29Z'><body>Art thou not Romeo, and a Montague?</body></from>
      <to secs='11'><body>Neither, fair saint, if either thee dislike.</body></to>
      <from secs='7'><body>How cam'st thou hither, tell me, and wherefore?</body></from>
    </chat>
  </save>
</iq>
    

5.6 Groupchat Messages

A client MAY archive messages that it receives from Multi-User Chat [9] rooms. The 'with' attribute MUST be the bare JID of the room. The client MUST include a 'name' attribute for each <from/> element to specify the room nickname (and, if available, bare JID) of the message sender:

Example 20. Storing groupchat messages in a collection

<iq type='set' id='up3'>
  <save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='balcony@house.capulet.com'
          start='1469-07-21T03:16:37Z'>
      <from secs='0' name='benvolio'><body>She will invite him to some supper.</body></from>
      <from secs='6' name='mercutio'><body>A bawd, a bawd, a bawd! So ho!</body></from>
      <from secs='3' name='romeo' jid='romeo@montague.net'><body>What hast thou found?</body></from>
    </chat>
  </save>
</iq>
    

5.7 Linking Collections

Collections MAY be linked together by including a <previous/> and/or <next/> element. Each such element MUST include both a 'with' and a 'start' element to identify the other collection to which the collection is linked. For example, the <previous/> and <next/> elements in the two examples below are being used to link a groupchat between Romeo, Benvolio and Mercutio to a private chat that Romeo was having with Benvolio before they invited Mercutio to join them. Note: Collections MAY be linked in only one direction, they are not required to be double-linked in the way the examples below are.

Example 21. Private chat linked to later groupchat

<iq type='set' id='link1'>
  <save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='benvolio@capulet.com'
          start='1469-07-21T03:01:54Z'>
      <next with='balcony@house.capulet.com' start='1469-07-21T03:16:37Z'/>
      <to secs='0'><body>O, I am fortune's fool!</body></from>
      <from secs='4'><body>Why dost thou stay?</body></from>
    </chat>
  </save>
</iq>
    

Example 22. Groupchat linked to earlier private chat

<iq type='set' id='link2'>
  <save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='balcony@house.capulet.com'
          start='1469-07-21T03:16:37Z'>
      <previous with='benvolio@capulet.com' start='1469-07-21T03:01:54Z'/>
      <from secs='0' name='benvolio'><body>She will invite him to some supper.</body></from>
      <from secs='6' name='mercutio'><body>A bawd, a bawd, a bawd! So ho!</body></from>
      <from secs='3' name='romeo'><body>What hast thou found?</body></from>
    </chat>
  </save>
</iq>
    

A collection MUST NOT contain more than one <previous/> and one <next/> element. If a <previous/> element is uploaded to a collection that already contains one then the older <previous/> element MUST be discarded. The same requirement applies for <next/> elements.

When a collection is retrieved (see Retrieving a Collection) the <previous/> and <next/> elements MUST appear as the first elements in the collection, whatever order they were uploaded in.

<previous/> and <next/> elements MAY be removed from a collection simply by uploading a <previous/> and/or <next/> element without any 'with' or 'start' attributes. Note: The server SHOULD NOT return an error if it finds that a link to be deleted does not exist.

Example 23. Deleting any links to other collections

<iq type='set' id='link3'>
  <save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='balcony@house.capulet.com'
          start='1469-07-21T03:16:37Z'>
      <previous/>
      <next/>
    </chat>
  </save>
</iq>
    

5.8 Associating Attributes with a Collection

A client MAY append attributes to a collection by including an x:data form of type 'submit' (see Data Forms [10]) when it uploads to a collection.

A collection MUST NOT contain more than one x:data form. If a form is uploaded to a collection that already contains one then the older form element MUST be discarded. When a collection is retrieved (see Retrieving a Collection) the x:data form MUST appear as the first element in the collection after any <previous/> or <next/> elements, whatever order it was uploaded in. Upon retrieval the 'type' attribute of the form MAY be 'submit' or 'form'.

Example 24. Private chat with attributes form

<iq type='set' id='form1'>
  <save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='benvolio@capulet.com'
          start='1469-07-21T03:01:54Z'>
      <x xmlns='jabber:x:data' type='submit'>
        <field var='FORM_TYPE'><value>http://www.xmpp.org/extensions/xep-0136.html#ns</value></field>
        <field var='task'><value>1</value></field>
        <field var='important'><value>1</value></field>
        <field var='action_before'><value>1469-07-29T12:00:00Z</value></field>
      </x>
      <to secs='0'><body>O, I am fortune's fool!</body></from>
      <from secs='4'><body>Why dost thou stay?</body></from>
    </chat>
  </save>
</iq>
    

The content of the uploaded x:data form MAY be encrypted (see Encryption).

Example 25. Private chat with encrypted attributes form

<iq type='set' id='form2'>
  <save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='benvolio@capulet.com'
          start='1469-07-21T03:01:54Z'>
      <x xmlns='jabber:x:data' type='submit'>
        <EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#'
                       Type='http://www.w3.org/2001/04/xmlenc#Content'>
          <EncryptionMethod Algorithm='http://www.w3.org/2001/04/xmlenc#aes128-cbc'/>
          <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
            <KeyName>dataKey1</KeyName>
          </KeyInfo>
          <CipherData><CipherValue>+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ</CipherValue></CipherData>
        </EncryptedData>
      </x>
      <EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
        <CarriedKeyName>dataKey1</CarriedKeyName>
        <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
        <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
          <KeyName>romeoPublicKey1fingerprint</KeyName>
        </KeyInfo>
        <CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
      </EncryptedKey>
    </chat>
  </save>
</iq>
    

The x:data form MAY be removed from a collection simply by uploading an empty form. Note: The server SHOULD NOT return an error if it finds that the form to be deleted does not exist.

Example 26. Deleting the attributes form

<iq type='set' id='form3'>
  <save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='benvolio@capulet.com'
          start='1469-07-21T03:01:54Z'>
      <x xmlns='jabber:x:data' type='submit'/>
    </chat>
  </save>
</iq>
    

6. Encryption

The examples above are not encrypted for clarity. However, clients SHOULD encrypt manually-archived collections (although early implementations of this protocol MAY prefer to defer encryption and decryption to later releases). Servers MUST support the manual-archiving of encrypted collections.

Before uploading a sequence of messages to a collection, the client SHOULD select a symmetric data encryption algorithm, generate a suitable random encryption key, give the key a unique (for the user) name, encrypt the symmetric key with one of the user's public keys, and wrap the result inside one or more <EncryptedKey/> elements, as specified in XML Encryption [11].

To ensure that all its user's clients will be able to decrypt the collection, the client SHOULD create one <EncryptedKey/> element for each of its user's public keys that are being published using Public Key Publishing [12]. However, the client MUST NOT create an <EncryptedKey/> element for any public key until it has confirmed that it belongs to the user. Note: The fact that a public key is being published using XEP-0189 is not sufficient proof of ownership, since the user's server may have been compromised at some stage. The method of confirmation is beyond the scope of this document.

The client SHOULD use the symmetric key to encrypt the joined sequence of <to/>, <from/> and <note/> elements, base64 encode the resulting sequence of bytes, and wrap it inside an <EncryptedData/> element, as described in XML Encryption.

Clients may add one or more <EncryptedData/> or <EncryptedKey/> elements to a collection using exactly the same method as for <to/>, <from/> and <note/> elements (see Uploading Messages to a Collection). One collection may contain <EncryptedData/> elements encrypted with different symmetric keys.

When appending <EncryptedData/> elements to a collection, the client MAY reuse a symmetric Key that has already been uploaded to the collection. In this case the client SHOULD NOT resend <EncryptedKey/> elements.

Note: A collection that contains <EncryptedData/> or <EncryptedKey/> elements MUST NOT contain <to/> or <from/> or <note/> elements.

Example 27. Storing encrypted messages and keys in a collection

<iq type='set' id='crypt1'>
  <save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='juliet@capulet.com/chamber'
          start='1469-07-23T19:22:31Z'
          subject='She speaks!'>
      <EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#'
                     Type='http://www.w3.org/2001/04/xmlenc#Content'>
        <EncryptionMethod Algorithm='http://www.w3.org/2001/04/xmlenc#aes128-cbc'/>
        <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
          <KeyName>dataKey1</KeyName>
        </KeyInfo>
        <CipherData><CipherValue>+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ</CipherValue></CipherData>
      </EncryptedData>
      <EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
        <CarriedKeyName>dataKey1</CarriedKeyName>
        <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
        <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
          <KeyName>romeoPublicKey1fingerprint</KeyName>
        </KeyInfo>
        <CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
      </EncryptedKey>
      <EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
        <CarriedKeyName>dataKey1</CarriedKeyName>
        <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
        <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
          <KeyName>romeoPublicKey2fingerprint</KeyName>
        </KeyInfo>
        <CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
      </EncryptedKey>
    </chat>
  </save>
</iq>
  

The <CipherData/> child of each <EncryptedData/> element contains the base64-encoded symmetric-encrypted messages. The <EncryptionMethod/> and <KeyInfo/> children specify the symmetric encryption algorithm and the name of the symmetric key used to encrypt the messages.

The <CarriedKeyName/> child of each <EncryptedKey/> element contains the name of the symmetric key it contains. The name is referenced by the <KeyName/> child of the <KeyInfo/> child of an <EncryptedData/> element. The <CipherData/> child of each <EncryptedKey/> element contains the base64-encoded public-key-encrypted symmetric key. The <EncryptionMethod/> and <KeyInfo/> children specify the public key encryption algorithm and the name of the public key used to encrypt the symmetric key. The name of the public key MAY refer to the name in the <KeyName/> child of one of the <KeyInfo/> elements that are being published using XEP-0189.

7. Automated Archiving

7.1 Toggling Auto-Archiving

If server administration policies require that every message is logged automatically (see Security Considerations) then:

Example 28. Server warns user of a legacy client about compulsory archiving

<message to='juliet@capulet.com/chamber'>
  <body>WARNING: All messages that you send or
        receive will be recorded by the server.</body>
</message>
    

Otherwise:

Example 29. Client enables auto archiving

<iq type='set' id='auto1'>
  <auto save='true' xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'/>
</iq>
    

7.2 Enabling Auto-Archiving with Encryption

Servers (and clients) SHOULD support the encryption (and decryption) of automatically-archived collections (although early implementations of this protocol MAY prefer to defer encryption and decryption to later releases).

Whenever the client enables auto-archiving it SHOULD set the optional 'encrypt' attribute to 'true'. After receiving such a request, if the server supports encryption (see Determining Server Support), it MUST encrypt all the messages that it archives automatically (including any message collections that are currently being recorded) by following exactly the same procedure as clients use when manually archiving collections (see Encryption).

The client MAY also specify one or more public keys (in addition to any public keys that the user may be publishing using XEP-0189). The server MUST use them all to encrypt all the symmetric keys it generates and add these to the collection wrapped in <EncryptedKey/> elements.

Example 30. Client enables auto archiving with encryption

<iq type='set' id='auto2'>
  <auto save='true'
        encrypt='true'
        xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
      <KeyValue>
        <KeyName>romeoPublicKey3fingerprint</KeyName>
        <RSAKeyValue>
          <Modulus>xA7SEU+e0yQH5rm9kbCDN9o3aPIo7HbP7tX6WOocLZAtNfyxSZDU16ksL6W
            jubafOqNEpcwR3RdFsT7bCqnXPBe5ELh5u4VEy19MzxkXRgrMvavzyBpVRgBUwUlV
            5foK5hhmbktQhyNdy/6LpQRhDUDsTvK+g9Ucj47es9AQJ3U=
          </Modulus>
          <Exponent>AQAB</Exponent>
        </RSAKeyValue>
      </KeyValue>
    </KeyInfo>
  </auto>
</iq>
    

As soon as the server has finished archiving a collection, it MUST securely destroy all copies of the symmetric key it used to encrypt the messages. Note: If the security of the server is compromised, then only the collections being recorded during the attack will be revealed (i.e. only those messages that would have been compromised even if they had not been archived).

7.3 Not-Implemented Responses

The server MUST return a <feature-not-implemented/> error in the following cases:

8. Archive Management

Manually uploaded and automatically saved collections are managed in the same way. There are three main areas of functionality related to archive management:

  1. Retrieving a list of collections
  2. Retrieving a collection
  3. Removing a collection

Requirements and protocol flows for each of these use cases are defined below. The protocols to retrieve a list of collections and an indivdual collection both make extensive use of Result Set Management [14]. Clients and servers SHOULD support all the features defined in that protocol.

8.1 Retrieving a List of Collections

To request a list of collections the client sends a <list/> element. The 'start' and 'end' attributes MAY be specified to indicate a date range (the values of these attributes MUST be UTC and adhere to the DateTime format specified in XEP-0082). The 'with' attribute MAY be specified to limit the list to a single participating full JID, bare JID or domain.

If the 'with' attribute is omitted then collections with any JID are returned. If only 'start' is specified then all collections on or after that date should be returned. If only 'end' is specified then all collections prior to that date should be returned.

The client SHOULD use Result Set Management to limit the number of collections returned by the server in a single stanza, taking care not to request a page of collections that is so big it might exceed karma limits.

Example 31. Requesting the first page of a list with same JID

<iq type='get' id='juliet1'>
  <list xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
        with='juliet@capulet.com'>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <max>30</max>
    </set>
  </list>
</iq>
    

Example 32. Requesting the first page of a list with same JID between two times

<iq type='get' id='period1'>
  <list xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
        with='juliet@capulet.com'
        start='1469-07-21T02:00:00Z'
        end='1479-07-21T04:00:00Z'>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <max>30</max>
    </set>
  </list>
</iq>
    

Example 33. Requesting the first page of a list after a time

<iq type='get' id='list1'>
  <list xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
        start='1469-07-21T02:00:00Z'>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <max>30</max>
    </set>
  </list>
</iq>
    

The server MUST list the collections (empty <chat/> elements including all attributes) in chronological order when responding to any request. If the collection contains <EncryptedData/> or <EncryptedKey/> elements then the 'crypt' attribute of the <chat/> element MUST be set to 'true':

Example 34. Receiving the first page of a list

<iq type='result' to='romeo@montague.net/orchard' id='list1'>
  <list xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='juliet@capulet.com/chamber'
          start='1469-07-21T02:56:15Z'
          subject='She speaks!'
          crypt='true'/>
    .
    [28 more collections]
    .
    <chat with='balcony@house.capulet.com'
          start='1469-07-21T03:16:37Z'/>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <first index='0'>1469-07-21T02:56:15Zjuliet@capulet.com</first>
      <last>1469-07-21T03:16:37Zbalcony@house.capulet.com</last>
      <count>1372</count>
    </set>
  </list>
</iq>
    

Note: In accordance with Result Set Management, the client MUST assume that the unique IDs it receives in the <first/> and <last/> elements are opaque. Servers MAY adopt a unique ID format other than the one suggested in the example above.

If no collections correspond to the request the server MUST return an empty <list/> element:

Example 35. Receiving an empty list

<iq type='result' to='romeo@montague.net/orchard' id='list1'>
  <list xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'/>
</iq>
    

Example 36. Requesting the second page of a list

<iq type='get' id='list2'>
  <list xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
        start='1469-07-21T02:00:00Z'>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <max>30</max>
      <after>1469-07-21T03:16:37Zbalcony@house.capulet.com</after>
    </set>
  </list>
</iq>
    

Refer to Result Set Management to learn more about the various ways that the pages of the list may be accessed.

8.2 Retrieving a Collection

To request a page of messages from a collection the client sends a <retrieve/> element. The 'with' and 'start' attributes specify the participating full JID and the start time (see XEP-0082). Both attributes MUST be included to uniquely identify a collection:

The client SHOULD use Result Set Management to limit the number of messages returned by the server in a single stanza, taking care not to request a page of messages that is so big it might exceed karma limits.

Example 37. Requesting the first page of a collection

<iq type='get' id='page1'>
  <retrieve xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
            with='juliet@capulet.com/chamber'
            start='1469-07-21T02:56:15Z'>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <max>100</max>
    </set>
  </retrieve>
</iq>
    

Example 38. Receiving the first page of a collection

<iq type='result' to='romeo@montague.net/orchard' id='page1'>
  <chat xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
        with='juliet@capulet.com/chamber'
        start='1469-07-21T02:56:15Z'
        subject='She speaks!'>
    <from secs='0'><body>Art thou not Romeo, and a Montague?</body></from>
    <to secs='11'><body>Neither, fair saint, if either thee dislike.</body></to>
    .
    [98 more messages]
    .
    <from secs='9'><body>How cam'st thou hither, tell me, and wherefore?</body></from>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <first index='0'>0</first>
      <last>99</last>
      <count>217</count>
    </set>
  </chat>
</iq>
    

Note: In accordance with Result Set Management, the client MUST assume the unique IDs it receives in the <first/> and <last/> elements are opaque. Servers MAY adopt a unique ID format other than the one suggested in the example above.

If the specified collection does not exist then the server MUST return an <item-not-found/> error:

Example 39. Unsuccessful reply

<iq type='error' to='romeo@montague.net/orchard' id='page1'>
  <retrieve xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
            with='juliet@capulet.com/chamber'
            start='1469-07-21T02:56:15Z'>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <max>100</max>
    </set>
  </retrieve>
  <error code='404' type='cancel'>
    <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>
    

If the requested collection is empty the server MUST return an empty <chat/> element:

Example 40. Receiving an empty collection

<iq type='result' to='romeo@montague.net/orchard' id='page1'>
  <chat xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
        with='juliet@capulet.com/chamber'
        start='1469-07-21T02:56:15Z'
        subject='She speaks!'/>
</iq>
    

Example 41. Requesting the second page of a collection

<iq type='get' id='page2'>
  <retrieve xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
            with='juliet@capulet.com/chamber'
            start='1469-07-21T02:56:15Z'>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <max>100</max>
      <after>99</after>
    </set>
  </retrieve>
</iq>
    

The items in encrypted collections are typically larger - since each <EncryptedData/> element typically contains many messages. So the client SHOULD take even more care not to request a page of <EncryptedData/> elements that is so big it might exceed karma limits.

Example 42. Requesting the first page of an encrypted collection with all versions of keys

<iq type='get' id='page1'>
  <retrieve xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
            with='juliet@capulet.com/chamber'
            start='1469-07-23T19:22:31Z'
    <set xmlns='http://jabber.org/protocol/rsm'>
      <max>5</max>
    </set>
  </retrieve>
</iq>
    

In addition to the requested <EncryptedData/> elements, the server MUST return all the <EncryptedKey/> elements that it possesses for the user whose symmetric key name (wrapped in its <CarriedKeyName/> child) is referenced by the <KeyName/> child of the <KeyInfo/> child of any of the <EncryptedData/> elements in the returned page.

Example 43. Receiving the first page of an encrypted collection

<iq type='result' to='romeo@montague.net/orchard' id='page1'>
  <chat xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
        with='juliet@capulet.com/chamber'
        start='1469-07-23T19:22:31Z'
        subject='She speaks!'>
    <EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#'
                   Type='http://www.w3.org/2001/04/xmlenc#Content'>
      <EncryptionMethod Algorithm='http://www.w3.org/2001/04/xmlenc#aes128-cbc'/>
      <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
        <KeyName>dataKey1</KeyName>
      </KeyInfo>
      <CipherData><CipherValue>+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ</CipherValue></CipherData>
    </EncryptedData>
    .
    [3 more <EncryptedData/> elements]
    .
    <EncryptedData xmlns='http://www.w3.org/2001/04/xmlenc#'
                   Type='http://www.w3.org/2001/04/xmlenc#Content'>
      <EncryptionMethod Algorithm='http://www.w3.org/2001/04/xmlenc#aes128-cbc'/>
      <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
        <KeyName>dataKey2</KeyName>
      </KeyInfo>
      <CipherData><CipherValue>+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ</CipherValue></CipherData>
    </EncryptedData>
    <EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
      <CarriedKeyName>dataKey1</CarriedKeyName>
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
      <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
        <KeyName>romeoPublicKey1fingerprint</KeyName>
      </KeyInfo>
      <CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
    </EncryptedKey>
    <EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
      <CarriedKeyName>dataKey1</CarriedKeyName>
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
      <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
        <KeyName>romeoPublicKey2fingerprint</KeyName>
      </KeyInfo>
      <CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
    </EncryptedKey>
    <EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
      <CarriedKeyName>dataKey2</CarriedKeyName>
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
      <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
        <KeyName>romeoPublicKey1fingerprint</KeyName>
      </KeyInfo>
      <CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
    </EncryptedKey>
    <EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
      <CarriedKeyName>dataKey2</CarriedKeyName>
      <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
      <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
        <KeyName>romeoPublicKey2fingerprint</KeyName>
      </KeyInfo>
      <CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
    </EncryptedKey>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <first index='0'>0</first>
      <last>4</last>
      <count>7</count>
    </set>
  </chat>
</iq>
    

The client MAY limit the number of <EncryptedKey/> elements that it receives by specifying the name of one or more public keys for which it holds the associated private keys. The name of each public key MUST be wrapped in a <KeyName/> element.

Example 44. Requesting the first page of an encrypted collection with specified version of keys

<iq type='get' id='page1'>
  <retrieve xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
            with='juliet@capulet.com/chamber'
            start='1469-07-23T19:22:31Z'>
    <KeyName xmlns='http://www.w3.org/2000/09/xmldsig#'>romeoPublicKey1fingerprint</KeyName>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <max>1</max>
    </set>
  </retrieve>
</iq>
    

If the request includes one or more <KeyName/> elements then the server MUST only return those <EncryptedKey/> elements whose public key name (wrapped in the <KeyName/> child of the <KeyInfo/> child) is specified in the request.

Refer to Result Set Management to learn more about the various ways that the pages of a collection may be accessed.

8.3 Removing a Collection

To request the removal of a single collection the client sends an empty <remove/> element. The 'with' (full JID) and 'start' attributes MUST be included to uniquely identify the collection.

Example 45. Removing a single collection

<iq type='set' id='remove1'>
  <remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
          with='juliet@capulet.com/chamber'
          start='1469-07-21T02:56:15Z'/>
</iq>
    

The client may remove several collections at once. The 'start' and 'end' elements MAY be specified to indicate a date range. The 'with' attribute MAY be a full JID, bare JID or domain.

Example 46. Removing all collections with a specified bare JID between two times

<iq type='set' id='remove2'>
  <remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
          with='juliet@capulet.com'
          start='1469-07-21T02:00:00Z'
          end='1469-07-21T04:00:00Z'/>
</iq>
    

If the 'with' attribute is omitted then collections with any JID are removed.

If the end date is in the future then then all collections after the start date are removed.

Example 47. Removing all collections after a date

<iq type='set' id='remove3'>
  <remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
          start='1469-07-21T02:00:00Z'
          end='2038-01-01T00:00:00Z'/>
</iq>
    

If the start date is before all the collections in the archive then all collections prior to the end date are removed.

Example 48. Removing all collections before a date

<iq type='set' id='remove4'>
  <remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
          start='0000-01-01T00:00:00Z'
          end='1469-07-21T04:00:00Z'/>
</iq>
    

Example 49. Removing all collections

<iq type='set' id='remove5'>
  <remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'/>
</iq>
    

If the value of the optional 'open' attribute is set to 'true' then only collections that are currently being recorded automatically by the server (see Automated Archiving) are removed.

Example 50. Removing a collection being recorded by the server

<iq type='set' id='remove6'>
  <remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
          with='juliet@capulet.com/chamber'
          open='true'/>
</iq>
    

Example 51. Removing all collections being recorded by the server

<iq type='set' id='remove7'>
  <remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
          open='true'/>
</iq>
    

If the specified collection (or collections) do not exist then the server MUST return an <item-not-found/> error:

Example 52. Unsuccessful reply

<iq type='error' to='romeo@montague.net/orchard' id='remove1'>
  <remove xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
          with='juliet@capulet.com/chamber'
          start='1469-07-21T02:56:15Z'/>
  <error code='404' type='cancel'>
    <item-not-found xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>
    

9. Replacing EncryptedKey Elements

If a private key becomes obsolete or compromised then it may be necessary for a client to replace all <EncryptedKey/> elements that contain symmetric keys encrypted with the public key that is associated with the obsolete private key.

The client first requests a list of the affected <EncryptedKey/> elements from all collections by sending a <keys/> element to the server:

Example 53. Requesting the first page of a list of keys

<iq type='get' id='pubkey1'>
  <keys xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <KeyName xmlns='http://www.w3.org/2000/09/xmldsig#'>romeoPublicKey1fingerprint</KeyName>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <max>50</max>
    </set>
  </keys>
</iq>
  

The server MUST return only <EncryptedKey/> elements whose symmetric encryption key is encrypted with the obsolete public key specified in the <KeyName/> child of the request:

Example 54. Receiving the first page of a list of keys

<iq type='result' to='romeo@montague.net/orchard' id='pubkey1'>
  <keys xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='juliet@capulet.com/chamber'
          start='1469-07-23T19:22:31Z'>
      <EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
        <CarriedKeyName>dataKey1</CarriedKeyName>
        <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
        <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
          <KeyName>romeoPublicKey1fingerprint</KeyName>
        </KeyInfo>
        <CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
      </EncryptedKey>
      <EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
        <CarriedKeyName>dataKey2</CarriedKeyName>
        <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
        <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
          <KeyName>romeoPublicKey1fingerprint</KeyName>
        </KeyInfo>
        <CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
      </EncryptedKey>
    </chat>
    .
    [49 more sets of collection keys]
    .
    <set xmlns='http://jabber.org/protocol/rsm'>
      <first index='0'>1469-07-23T19:22:31Zjuliet@capulet.com</first>
      <last>1469-08-03T13:24:06Zbalcony@house.capulet.com</last>
      <count>3810</count>
    </set>
  </keys>
</iq>
  

The client decrypts each symmetric key with the obsolete private key and encrypts it again with the new public key. The client then wraps each symmetric key in an <EncryptedKey/> element and asks the server to archive it in its associated collection on the server (see Encryption):

Example 55. Storing encrypted keys in a collection

<iq type='set' id='crypt1'>
  <save xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <chat with='juliet@capulet.com/chamber'
          start='1469-07-23T19:22:31Z'>
      <EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
        <CarriedKeyName>dataKey1</CarriedKeyName>
        <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
        <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
          <KeyName>romeoPublicKey2fingerprint</KeyName>
        </KeyInfo>
        <CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
      </EncryptedKey>
      <EncryptedKey xmlns='http://www.w3.org/2001/04/xmlenc#'>
        <CarriedKeyName>dataKey2</CarriedKeyName>
        <EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-1_5"/>
        <KeyInfo xmlns='http://www.w3.org/2000/09/xmldsig#'>
          <KeyName>romeoPublicKey2fingerprint</KeyName>
        </KeyInfo>
        <CipherData><CipherValue>E5Qbvfa2gI5lBZMAHryv4g</CipherValue></CipherData>
      </EncryptedKey>
    </chat>
  </save>
</iq>
.
[49 more sets of collection keys]
.
  

Finally, the client asks the server to delete from each collection all <EncryptedKey/> elements whose symmetric encryption key is encrypted with the obsolete public key:

Example 56. Deleting key(s) from a collection

<iq type='get' id='delete1'>
  <delete xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
          with='juliet@capulet.com/chamber'
          start='1469-07-23T19:22:31Z'>
    <KeyName xmlns='http://www.w3.org/2000/09/xmldsig#'>romeoPublicKey1fingerprint</KeyName>
  </delete>
</iq>
.
[49 more delete requests]
.
  

10. Replication

This section describes how a client MAY replicate an archive locally. [15] The existence of a local copy of the archive enables clients to search the content of all messages (including collections saved by another client machine). [16]

The client MAY 'synchronize' its local copy of the archive with the 'master' archive on the server at any time. The first step is to request the list of collections that the server has changed (created, modified or removed) in its master archive since the last update to the client's copy of the archive.

The client MUST request each page of the list using the Result Set Management protocol embedded in a <modified/> element. The content of the <after/> element SHOULD be a UTC time (see XEP-0082) that it has previously received from the server (see below). When synchronizing for the first time, the client MAY choose a suitable time for the first page request (e.g. 1970-01-01T00:00:00Z).

Example 57. Requesting a page of modifications

    
<iq type='get' id='sync1'>
  <modified xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <max>50</max>
      <after>1469-07-21T01:14:47Z</after>
    </set>
  </modified>
</iq>
  

The server MUST return the changed collections in the chronological order that they were changed (most recent last). If a collection has been modified, created or removed after the time specified by the <after/> element then the server MUST include it in the returned result set page of collections (unless the specified maximum page size would be exceeded). Each <changed/> or <removed/> collection element (for modified/created, or removed collections respectively) in the returned list MUST include only 'with' and 'start' attribues. The server MUST set the content of the <last/> element to the UTC time (see XEP-0082) that the last collection on the page was modified.

Example 58. Receiving a page of modifications

<iq type='result' to='romeo@montague.net/orchard' id='sync1'>
  <modified xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
    <changed with='juliet@capulet.com/chamber'
             start='1469-07-21T02:56:15Z'/>
    .
    [up to 48 more collections]
    .
    <removed with='balcony@house.capulet.com'
             start='1469-07-21T03:16:37Z'/>
    <set xmlns='http://jabber.org/protocol/rsm'>
      <last>1469-07-21T04:22:39Z</last>
      <count>1372</count>
    </set>
  </modified>
</iq>
  

Note: The server should remember the 'with' and 'start' attribues and the time of removal of all deleted collections. If this "state" cannot be maintained indefinitely, then unless all the user's clients replicate before the server deletes its memory of a removal then it will not be reflected in all the local copies of the archive.

Note: Along with its copy of the archive the client SHOULD save the most recent <last/> time that it received from the server. The next time it synchronizes with the server it SHOULD specify that time when requesting the first result set page (see above).

After receiving each result set page the client SHOULD delete from its local archive any collections that have been removed from the master archive. The client should also retrieve from the server the content of each collection that has been modified (see Retrieving a Collection) and add it to its local copy of the archive (deleting any older version of the same collection that it may already have).

11. File Format

Note the file format specified in this section is likely to be deprecated once a standards-based format has been published in a separate specification.

So that clients can share archived messages, this document specifies a common format for storage on disk (similar to email formats like mbox and Maildir). The file format uses the same XML constructs as the protocol. Each file may contain messages exchanged with a single JID. Any number of <chat/> elements may be stored in an archive file.

Example 59. Example file

<?xml version='1.0'?>
<archive xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
         with='juliet@capulet.com'>
  <chat start='1469-07-21T02:56:15Z' subject='She speaks!'>
    <from secs='0'><body>Art thou not Romeo, and a Montague?</body></from>
    <to secs='11'><body>Neither, fair saint, if either thee dislike.</body></to>
    <from secs='7'><body>How cam'st thou hither, tell me, and wherefore?</body></from>
  </chat>
</archive>
  

12. Implementation Notes

12.1 Time Synchronization

When creating a new collection, it is RECOMMENDED that the client synchronizes the collection start time that it sends to the server with server time. This is important since the user may subsequently retrieve the archived collection using client machines whose UTC clocks are not synchronized with the client machine that uploaded the collection. (i.e. Either or both of the clients' UTC clocks may be wrong.) The client can achieve this synchronization with server time by using Entity Time [17] to estimate the difference between the server and client UTC clocks.

When retrieving collections, it is RECOMMENDED that the client adjusts the start times of the collections it receives from server to be synchronized with the clock of the client machine.

12.2 Bandwidth Considerations

When uploading messages using manual archiving, a client SHOULD NOT upload one message at a time to the server since this increases both bandwidth consumption and the total number of transactions. It is instead RECOMMENDED that clients upload messages only when the conversation thread appears to be terminated, e.g. when the user closes the chat window. If the user reopens the window and the thread continues then the client should append the new messages to the collection when the user closes the window again.

12.3 Storage Considerations

Server implementations SHOULD give system administrators the option to disable support for both automated and manual archiving, since archived conversations can consume significant storage space.

13. Stream Feature

Although message archiving is not negotiated between a client and its server as part of stream negotiation, a server MAY advertise a stream feature of "http://www.xmpp.org/extensions/xep-0136.html#ns" (see Protocol Namespaces regarding issuance of one or more permanent namespaces) during stream setup (via the <feature/> element, which MUST NOT contain a <required/> child), and MUST do so if automatic archiving is on by default (if so, the <feature/> element MUST include a <default/> child).

Example 60. Stream Feature

<feature xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'/>
  

Example 61. Stream Feature (Automatic Archiving on By Default)

<feature xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'>
  <default/>
</feature>
  

14. Security Considerations

14.1 Automatic Archiving Defaulting to On

If automatic archiving defaults to enabled then that creates serious privacy issues for users of legacy clients that do not support this protocol, and (more seriously) for those contacts who they unwittingly mislead by agreeing to disable logging (via the 'logging' field defined in XEP-0155).

If a server deployment enables automatic archiving by default, then it MUST return a stream feature containing an empty <default/> element (see the Stream Feature section of this document).

14.2 Plain Text Subject

Since the subject of each collection will not be encrypted, the client MUST warn its human user (if any) before including 'subject' attributes on encrypted collections.

14.3 Store Headers

The client that originates a message MAY specify a 'false' value for the 'store' header (see Stanza Headers and Internet Metadata [18]). The recipient MUST NOT archive such a message or any of the information it contains.

If the sender plans to use 'store' headers it MUST use Service Discovery to determine whether or not the recipient supports them. Note: Since servers are not required to check the content of message stanzas for headers, if the recipient is using automatic archiving then it MUST indicate that it does not support 'store' headers.

If the recipient does not support 'store' headers, then the sender MUST confirm with its human user (if any) before sending such a message.

15. IANA Considerations

No interaction with the Internet Assigned Numbers Authority (IANA) [19] is required as a result of this document.

16. XMPP Registrar Considerations

16.1 Protocol Namespace

Until this specification advances to a status of Draft, its associated namespace shall be "http://www.xmpp.org/extensions/xep-0155.html#ns"; upon advancement of this specification, the XMPP Registrar [20] shall issue a permanent namespace in accordance with the process defined in Section 4 of XMPP Registrar Function [21].

16.2 Service Discovery Features

The XMPP Registrar shall include the following features in its registry of service discovery features (see <http://www.xmpp.org/registrar/disco-features.html>), where the string "http://www.xmpp.org/extensions/xep-0136.html#ns" shall be replaced with the URN issued by the XMPP Registrar:

16.3 Field Standardization

Field Standardization for Data Forms [22] defines a process for standardizing the fields used within Data Forms qualified by a particular namespace. The following fields shall be registered for use in Message Archiving, where the FORM_TYPE "http://www.xmpp.org/extensions/xep-0136.html#ns" shall be replaced with the URN issued by the XMPP Registrar:

Registry Submission

<form_type>
  <name>http://www.xmpp.org/extensions/xep-0136.html#ns</name>
  <doc>XEP-0136</doc>
  <desc>Attributes of a message collection stored using Message Archiving</desc>
  <field
       var='task'
       type='boolean'
       label='Collection contains
              information about a task'/>
  <field
       var='important'
       type='boolean'
       label='Collection is important'/>
  <field
       var='action_before'
       type='text-single'
       label='Datetime (see XEP-0082) before
              the action discussed in the
              collection must be completed'/>
</form_type>
    

17. XML Schemas

<?xml version='1.0' encoding='UTF-8'?>

<xs:schema
    xmlns:xs='http://www.w3.org/2001/XMLSchema'
    targetNamespace='http://www.xmpp.org/extensions/xep-0136.html#ns'
    xmlns='http://www.xmpp.org/extensions/xep-0136.html#ns'
    elementFormDefault='qualified'>

  <xs:annotation>
    <xs:documentation>
      The allowable root elements for the namespace defined
      herein are:
        - archive
        - auto
        - chat
        - delete
        - keys
        - list
        - modified
        - pref
        - remove
        - retrieve
        - save
    </xs:documentation>
  </xs:annotation>

  <xs:element name='archive'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='chat' minOccurs='1' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='with' type='xs:string' use='optional'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='auto'>
    <xs:complexType>
      <xs:sequence>
        <xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='encrypt' type='xs:boolean' use='optional'/>
      <xs:attribute name='save' type='xs:boolean' use='required'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='changed'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='start' type='xs:dateTime' use='required'/>
          <xs:attribute name='with' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name='chat'>
    <xs:complexType>
      <xs:choice minOccurs='0' maxOccurs='unbounded'>
        <xs:element name='from' type='messageType'/>
        <xs:element name='next' type='linkType'/>
        <xs:element ref='note'/>
        <xs:element name='previous' type='linkType'/>
        <xs:element name='to' type='messageType'/>
        <xs:any processContents='lax' namespace='##other'/>
      </xs:choice>
      <xs:attribute name='crypt' use='optional' type='xs:boolean'/>
      <xs:attribute name='start' type='xs:dateTime' use='required'/>
      <xs:attribute name='subject' type='xs:string' use='optional'/>
      <xs:attribute name='thread' use='optional' type='xs:string'/>
      <xs:attribute name='with' type='xs:string' use='required'/>
    </xs:complexType>
  </xs:element>

  <xs:complexType name='messageType'>
    <xs:sequence>
      <xs:element name='body' type='xs:string' minOccurs='0' maxOccurs='unbounded'/>
      <xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
    </xs:sequence>
    <xs:attribute name='jid' type='xs:string' use='optional'/>
    <xs:attribute name='name' type='xs:string' use='optional'/>
    <xs:attribute name='secs' type='xs:nonNegativeInteger' use='optional'/>
    <xs:attribute name='utc' type='xs:dateTime' use='optional'/>
  </xs:complexType>

  <xs:complexType name='linkType'>
    <xs:simpleContent>
      <xs:extension base='empty'>
        <xs:attribute name='start' type='xs:dateTime' use='optional'/>
        <xs:attribute name='with' type='xs:string' use='optional'/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>

  <xs:element name='default'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='expire' type='xs:nonNegativeInteger' use='optional'/>
          <xs:attribute name='otr' use='required'>
            <xs:simpleType>
              <xs:restriction base='xs:NCName'>
                <xs:enumeration value='approve'/>
                <xs:enumeration value='concede'/>
                <xs:enumeration value='forbid'/>
                <xs:enumeration value='oppose'/>
                <xs:enumeration value='prefer'/>
                <xs:enumeration value='require'/>
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
          <xs:attribute name='save' use='required'>
            <xs:simpleType>
              <xs:restriction base='xs:NCName'>
                <xs:enumeration value='body'/>
                <xs:enumeration value='false'/>
                <xs:enumeration value='message'/>
                <xs:enumeration value='stream'/>
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
          <xs:attribute name='unset' use='optional' type='xs:boolean'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name='delete'>
    <xs:complexType>
      <xs:sequence>
        <xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='start' type='xs:dateTime' use='required'/>
      <xs:attribute name='with' type='xs:string' use='required'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='feature'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='default' minOccurs='0' maxOccurs='1'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name='item'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='expire' type='xs:nonNegativeInteger' use='optional'/>
          <xs:attribute name='jid' use='required' type='xs:string'/>
          <xs:attribute name='otr' use='required'>
            <xs:simpleType>
              <xs:restriction base='xs:NCName'>
                <xs:enumeration value='approve'/>
                <xs:enumeration value='concede'/>
                <xs:enumeration value='forbid'/>
                <xs:enumeration value='oppose'/>
                <xs:enumeration value='prefer'/>
                <xs:enumeration value='require'/>
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
          <xs:attribute name='save' use='required'>
            <xs:simpleType>
              <xs:restriction base='xs:NCName'>
                <xs:enumeration value='body'/>
                <xs:enumeration value='false'/>
                <xs:enumeration value='message'/>
                <xs:enumeration value='stream'/>
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name='keys'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='chat' minOccurs='0' maxOccurs='unbounded'/>
        <xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name='list'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='chat' minOccurs='0' maxOccurs='unbounded'/>
        <xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='end' type='xs:dateTime' use='optional'/>
      <xs:attribute name='start' type='xs:dateTime' use='optional'/>
      <xs:attribute name='with' type='xs:string' use='optional'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='method'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='type' type='xs:string' use='required'/>
          <xs:attribute name='use' use='required'>
            <xs:simpleType>
              <xs:restriction base='xs:NCName'>
                <xs:enumeration value='concede'/>
                <xs:enumeration value='forbid'/>
                <xs:enumeration value='prefer'/>
              </xs:restriction>
            </xs:simpleType>
          </xs:attribute>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name='modified'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='changed' minOccurs='0' maxOccurs='unbounded'/>
        <xs:element ref='removed' minOccurs='0' maxOccurs='unbounded'/>
        <xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name='note'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='xs:string'>
          <xs:attribute name='utc' type='xs:dateTime' use='optional'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name='pref'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='auto' minOccurs='0' maxOccurs='1'/>
        <xs:element ref='default' minOccurs='0' maxOccurs='1'/>
        <xs:element ref='item' minOccurs='0' maxOccurs='unbounded'/>
        <xs:element ref='method' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name='remove'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='end' type='xs:dateTime' use='optional'/>
          <xs:attribute name='open' use='optional' type='xs:boolean'/>
          <xs:attribute name='start' type='xs:dateTime' use='required'/>
          <xs:attribute name='with' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name='removed'>
    <xs:complexType>
      <xs:simpleContent>
        <xs:extension base='empty'>
          <xs:attribute name='start' type='xs:dateTime' use='required'/>
          <xs:attribute name='with' type='xs:string' use='required'/>
        </xs:extension>
      </xs:simpleContent>
    </xs:complexType>
  </xs:element>

  <xs:element name='retrieve'>
    <xs:complexType>
      <xs:sequence>
        <xs:any processContents='lax' namespace='##other' minOccurs='0' maxOccurs='unbounded'/>
      </xs:sequence>
      <xs:attribute name='start' type='xs:dateTime' use='required'/>
      <xs:attribute name='with' type='xs:string' use='required'/>
    </xs:complexType>
  </xs:element>

  <xs:element name='save'>
    <xs:complexType>
      <xs:sequence>
        <xs:element ref='chat' minOccurs='1' maxOccurs='1'/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:simpleType name='empty'>
    <xs:restriction base='xs:string'>
      <xs:enumeration value=''/>
    </xs:restriction>
  </xs:simpleType>

</xs:schema>
  

Notes

1. XEP-0030: Service Discovery <http://www.xmpp.org/extensions/xep-0030.html>.

2. The "OTR" mode for message archiving is not to be confused with the "OTR" technology for "off-the-record communications" described at <http://www.cypherpunks.ca/otr/>.

3. In accordance with Section 3.2.2.1 of XML Schema Part 2: Datatypes, the allowable lexical representations for the xs:boolean datatype are the strings "0" and "false" for the concept 'false' and the strings "1" and "true" for the concept 'true'; implementations MUST support both styles of lexical representation.

4. Stream compression typically does not mitigate bandwidth and storage issues since collections SHOULD be encrypted, and since clients running in constrained runtime environments typically cannot take advantage of stream compression (no binary data, only XML, may be transfered).

5. If a client (or user) acts in bad faith then its contacts cannot prevent it from archiving conversations.

6. XEP-0116: Encrypted Session Negotiation <http://www.xmpp.org/extensions/xep-0116.html>.

7. XEP-0082: XMPP Date and Time Profiles <http://www.xmpp.org/extensions/xep-0082.html>.

8. XEP-0201: Best Practices for Message Threads <http://www.xmpp.org/extensions/xep-0201.html>.

9. XEP-0045: Multi-User Chat <http://www.xmpp.org/extensions/xep-0045.html>.

10. XEP-0004: Data Forms <http://www.xmpp.org/extensions/xep-0004.html>.

11. XML Encryption Syntax and Processing <http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/>.

12. XEP-0189: Public Key Publishing <http://www.xmpp.org/extensions/xep-0189.html>.

13. XEP-0116: Encrypted Session Negotiation <http://www.xmpp.org/extensions/xep-0116.html>.

14. XEP-0059: Result Set Management <http://www.xmpp.org/extensions/xep-0059.html>.

15. Clients that run in constrained environments may not be able to implement replication if they are prevented from accessing (sufficient) local storage.

16. Since collections SHOULD be stored on the server in a form that it cannot decrypt, server-side searching of the content of messages is beyond the scope of this protocol.

17. XEP-0202: Entity Time <http://www.xmpp.org/extensions/xep-0202.html>.

18. XEP-0131: Stanza Headers and Internet Metadata <http://www.xmpp.org/extensions/xep-0131.html>.

19. The Internet Assigned Numbers Authority (IANA) is the central coordinator for the assignment of unique parameter values for Internet protocols, such as port numbers and URI schemes. For further information, see <http://www.iana.org/>.

20. The XMPP Registrar maintains a list of reserved protocol namespaces as well as registries of parameters used in the context of XMPP extension protocols approved by the XMPP Standards Foundation. For further information, see <http://www.xmpp.org/registrar/>.

21. XEP-0053: XMPP Registrar Function <http://www.xmpp.org/extensions/xep-0053.html>.

22. XEP-0068: Field Data Standardization for Data Forms <http://www.xmpp.org/extensions/xep-0068.html>.


Revision History

Version 0.14 (2007-08-16)

Clarified text regarding preference syntax; completed copy edit.

(psa)

Version 0.13 (2007-01-08)

Harmonized stanza session negotiation of message logging settings with XEP-0155; defined stream feature.

(psa/ip)

Version 0.12 (2006-11-23)

All modes allow multiple body children of to and from elements; changed namespace and collection element name to chat; renamed all value of save attribute to message; added stream value of the save attribute, thread attribute, save wrapper element, and Linking Collections and Associating Attributes sections

(ip)

Version 0.11 (2006-11-06)

Added more otr attribute values and clarified their meanings, changed the names of the use attribute values

(ip)

Version 0.10 (2006-10-11)

Added auto-archiving warning for legacy clients; corrected examples

(ip)

Version 0.9 (2006-10-02)

Added method child elements and expire attribute to pref element

(ip)

Version 0.8 (2006-09-29)

Server generates encryption secrets for auto-archiving; specified use of W3C XML Encryption standard; enabled replacement of keys encrypted with an obsolete public key; enabled removal of open collections

(ip)

Version 0.7 (2006-09-08)

Added preferences, results set management and notes; reinstated encryption and replication; simplified auto-archiving and off-the-record (with XEP-0155); many minor changes

(ip)

Version 0.6 (2006-08-18)

Added unset value for save attribute and added service attribute on default element; added source attribute on record element; specified that services should (not must) support save mode for particular contacts.

(jp/psa)

Version 0.5 (2006-05-03)

Integrated text from server-side archiving proposal; added partial support to collection retrieval; harmonized XML formats and namespaces; defined XMPP Registrar considerations and XML schema.

(psa/jp/jk)

Version 0.4 (2005-12-21)

Added Replication and Searching section, partial attribute; minor improvements

(ip)

Version 0.3 (2005-10-21)

Added more examples to Removing Collections

(ip)

Version 0.2 (2005-04-18)

Complete rewrite.

(ip)

Version 0.1 (2004-06-04)

Initial version.

(jk)

END