XEP-0248: PubSub Collection Nodes

Abstract
This specification defines the nature and handling of collection nodes in the XMPP publish-subscribe extension.
Authors
  • Peter Saint-Andre
  • Ralph Meijer
  • Brian Cully
Copyright
© 2008 – 2025 XMPP Standards Foundation. SEE LEGAL NOTICES.
Status

Deferred

WARNING: This document has been automatically Deferred after 12 months of inactivity in its previous Experimental state. Implementation of the protocol described herein is not recommended for production systems. However, exploratory implementations are encouraged to resume the standards process.
Type
Standards Track
Version
0.5.0 (2025-09-11)
Document Lifecycle
  1. Experimental
  2. Deferred
  3. Proposed
  4. Stable
  5. Final

1. Introduction

Publish-Subscribe (XEP-0060) [1] defines an XMPP protocol extension for generic publish-subscribe features. However, it only allows notifications from nodes to which an entity is directly subscribed. It is useful in some circumstances to describe a relationship between nodes so that a publish on one node may be delivered via another node. For instance, if an entity is interested in notifications from a set of nodes the entity would discover each node somehow and then subscribe to them. With collection nodes, the entity would subscribe only to the collection which links the desired nodes, simplifying the subscription process.

In addition to simplifying the subscriber's usage, collection nodes also allow the owner to describe almost any type of relationship between nodes. Using various access models on different nodes the owner can also create almost any desired authorization semantics on a set of leaf nodes.

Note: Any use cases not described herein are described in Publish-Subscribe (XEP-0060) [1]. Also, this document does not show error flows related to the generic publish-subscribe use cases referenced herein, since they are exhaustively defined in XEP-0060. The reader is referred to XEP-0060 for all relevant protocol details related to the XMPP publish-subscribe extension.

2. Scope

This documents addresses the common requirements regarding configuration, publishing, subscribing, and notification semantics of collection nodes.

3. Glossary

The following terms are used in this document to refer to collection node-specific features.

Note: some of these terms are specified in greater detail within the body of this document.

Collection Node
A type of node that contains other nodes but no published items (c.f. Leaf Node).
Leaf Node
A type of node that contains published items but no other nodes (c.f. Collection Node).
Node Graph
The network of nodes emitting from a given node which contains all its descendants.
Root Node
An anonymous collection node used as the de facto beginning of a service's node graph.
Subscription Depth
How deep the collection node graph will be traversed when determining whether notifications will be sent. May be any integer, 0 or greater, or "all".
Subscription Type
The type of notification, either "nodes", "items", or "all" which the subscriber is interested in.

4. Preliminaries

4.1 Collection Nodes

Collection nodes link nodes together to unify notifications from a set of collection or leaf nodes. An entity can subscribe to the collection and receive notifications of any associated leaf nodes.

A collection node can link with any other node in order to create a directed acyclic graph (DAG). Collection nodes MUST NOT be linked in such a way as to produce a cyclic graph (i.e., they cannot link to nodes that eventually link back to the initial node).

Collection nodes only contain other nodes and MUST NOT contain published items (therefore a collection MUST NOT support the "publish" feature or related features such as "persistent-items").

5. Entity Use Cases

5.1 Discovering Support for Collection Nodes

An entity might wish to discover if a service implements collection nodes; in order to do so, it sends a service discovery information ("disco#info") query to the component's JID using Service Discovery (XEP-0030) [2]. If a service supports collection nodes it MUST return a "pubsub#collections" feature. In addition, if the service supports associating a node with more than one collection it MUST return a feature of "pubsub#multi-collections".

Example 1. Entity requests features from a service
<iq type='get'
    from='francisco@denmark.lit/barracks'
    to='pubsub.shakespeare.lit'
    id='info1'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
Example 2. Service responds with support for collections
<iq type='result'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='info1'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
    ...
    <feature var='http://jabber.org/protocol/pubsub#collections'/>
    <feature var='http://jabber.org/protocol/pubsub#multi-collections'/>
    ...
  </query>
</iq>

5.2 Discover Nodes

If a service implements a hierarchy of nodes, it MUST also enable entities to discover the nodes in that hierarchy by means of the Service Discovery protocol, subject to the recommendations in Service Discovery (XEP-0030) [2] regarding large result sets (for which Jabber Search (XEP-0055) [3] or some other protocol SHOULD be used). The service discovery items ("disco#items") protocol enables an entity to query a service for a list of associated items, which, in the case of collection nodes would consist of the children associated with a given node. The following examples show the use of service discovery in discovering the nodes available at a hierarchical pubsub service.

In the first example, an entity sends a service discovery items ("disco#items") request to the root node (i.e., the service itself):

Example 3. Entity asks service for all first-level nodes
<iq type='get'
    from='francisco@denmark.lit/barracks'
    to='pubsub.shakespeare.lit'
    id='nodes1'>
  <query xmlns='http://jabber.org/protocol/disco#items'/>
</iq>
Example 4. Service returns all first-level nodes
<iq type='result'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='nodes1'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <item jid='pubsub.shakespeare.lit'
          node='blogs'
          name='Weblog updates'/>
    <item jid='pubsub.shakespeare.lit'
          node='news'
          name='News and announcements'/>
  </query>
</iq>

In the second example, an entity sends a disco#items request to one of the first-level nodes, which is also a collection node:

Example 5. Entity requests second-level nodes
<iq type='get'
    from='francisco@denmark.lit/barracks'
    to='pubsub.shakespeare.lit'
    id='nodes2'>
  <query xmlns='http://jabber.org/protocol/disco#items'
         node='blogs'/>
</iq>
Example 6. Service returns second-level nodes
<iq type='result'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='nodes2'>
  <query xmlns='http://jabber.org/protocol/disco#items'
         node='blogs'>
    <item jid='pubsub.shakespeare.lit'
          node='princely_musings'/>
    <item jid='pubsub.shakespeare.lit'
          node='kingly_ravings'/>
    <item jid='pubsub.shakespeare.lit'
          node='starcrossed_stories'/>
    <item jid='pubsub.shakespeare.lit'
          node='moorish_meanderings'/>
  </query>
</iq>

5.3 Notifications

5.3.1 Generating Notifications for Collections

If a notification on a child node is created and then delivered via the collection then the notifications generated by the service MUST contain additional information. The 'node' attribute of the <item/> or <node/> element contained in the notification message MUST specify the node identifier of the node that generated the notification (not the collection) and the <message/> stanza MUST contain Stanza Headers and Internet Metadata (XEP-0131) [4] that specifies the node identifier of the collection.

Note: The delivery options (such as "pubsub#deliver_payloads") are determined by the publishing leaf node, not by the collection node. If the owner of a collection node sets delivery options for a collection node, the service SHOULD ignore those options and apply the options set for the leaf node that publishes an item.

5.3.1.1 Notifications about Items

Item notifications are notifications about the contents of a leaf node, and are generated by a publish, retract, or purge request.

Example 7. Subscriber receives a publish notification from a collection
<message to='francisco@denmark.lit' from='pubsub.shakespeare.lit'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <items node='princely_musings'>
      <item id='ae890ac52d0df67ed7cfdf51b644e901'>
        ...
      </item>
    </items>
  </event>
  <headers xmlns='http://jabber.org/protocol/shim'>
    <header name='Collection'>blogs</header>
  </headers>
</message>
5.3.1.2 Notifications about Nodes

Node notifications are notifications about nodes themselves, and are generated by a create, delete, or configure request.

Example 8. Subscriber receives a creation notification from a collection
<message to='francisco@denmark.lit' from='pubsub.shakespeare.lit'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <create node='princely_musings'/>
  </event>
  <headers xmlns='http://jabber.org/protocol/shim'>
    <header name='Collection'>blogs</header>
  </headers>
</message>

5.3.2 Node Association and Dissociation

If a collection node is configured to send notification of node associations and disassociations, the service shall send an event that contains a <collection/> element whose 'node' attribute specifies the NodeID of the collection; this element in turn contains an <associate/> or <dissociate/> element whose 'node' attribute specifies the NodeID of node that has been associated with the collection.

Example 9. Notification of node association
<message from='pubsub.shakespeare.lit'
         to='francisco@denmark.lit'
         id='newnode1'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <collection node='some-collection'>
      <associate node='new-node-id'>
    </collection>
  </event>
</message>
Example 10. Notification of node dissociation
<message from='pubsub.shakespeare.lit'
         to='francisco@denmark.lit'
         id='newnode1'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <collection node='some-collection'>
      <dissociate node='old-node-id'>
    </collection>
  </event>
</message>
5.3.2.1 Including Node Meta-Data

The notification event MAY also include the node metadata, formatted using the Data Forms (XEP-0004) [5] protocol.

Example 11. Notification of node association
<message from='pubsub.shakespeare.lit'
         to='francisco@denmark.lit'
         id='newnode2'>
  <event xmlns='http://jabber.org/protocol/pubsub#event'>
    <collection node='some-collection'>
      <associate node='new-node-id'>
        <x xmlns='jabber:x:data' type='result'>
          <field var='FORM_TYPE' type='hidden'>
            <value>http://jabber.org/protocol/pubsub#meta-data</value>
          </field>
          <field var='pubsub#creation_date'>
            <value>2003-07-29T22:56Z</value>
          </field>
          <field var='pubsub#creator'>
            <value>hamlet@denmark.lit</value>
          </field>
          <field var='pubsub#description'>
            <value>Atom feed for my blog.</value>
          </field>
          <field var='pubsub#language'>
            <value>en</value>
          </field>
          <field var='pubsub#contact'>
            <value>bard@shakespeare.lit</value>
          </field>
          <field var='pubsub#owner'>
            <value>hamlet@denmark.lit</value>
          </field>
          <field var='pubsub#title'>
            <value>Princely Musings (Atom).</value>
          </field>
          <field var='pubsub#type'
            ><value>http://www.w3.org/2005/Atom</value>
          </field>
        </x>
      </node>
    </collection>
  </event>
</message>

6. Subscriber Use Cases

6.1 Subscribe to a Collection Node

A service that implements collection nodes SHOULD allow entities to subscribe to collection nodes (subject to access models and local security policies).

In addition to the subscription configuration options already defined in Publish-Subscribe (XEP-0060) [1], there are two subscription configuration options specific to collection nodes:

In order to subscribe to a collection node, an entity MUST send a subscription request to the node; the subscription request MAY include subscription options, but this is not strictly necessary (especially if the entity does not wish to override the default settings for the "pubsub#subscription_type" and "pubsub#subscription_depth" options).

6.1.1 Request

Example 12. Entity subscribes to a collection node (no configuration)
<iq type='set'
    from='francisco@denmark.lit/barracks'
    to='pubsub.shakespeare.lit'
    id='collsub1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe jid='francisco@denmark.lit'
               node='blogs'/>
  </pubsub>
</iq>

The subscriber will now receive notification of new first-level nodes created within the "blogs" collection.

Example 13. Entity subscribes to a collection node (with configuration)
<iq type='set'
    from='francisco@denmark.lit/barracks'
    to='pubsub.shakespeare.lit'
    id='collsub1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe jid='francisco@denmark.lit'
               node='blogs'/>
    <options>
      <x xmlns='jabber:x:data' type='submit'>
        <field var='FORM_TYPE' type='hidden'>
          <value>http://jabber.org/protocol/pubsub#subscribe_options</value>
        </field>
        <field var='pubsub#subscription_type'>
          <value>items</value>
        </field>
        <field var='pubsub#subscription_depth'>
          <value>all</value>
        </field>
      </x>
    </options>
  </pubsub>
</iq>

6.1.2 Success Case

If the service allows the subscription it MUST inform the requesting entity that it is now subscribed.

Example 14. Service responds with success
<iq type='result'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='collsub1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscription node='blogs'
                  jid='francisco@denmark.lit'
                  subscription='subscribed'/>
  </pubsub>
</iq>

6.1.3 Error Cases

A service MAY allow an entity to subscribe to a collection node in two ways, once with a subscription of type "nodes" (to receive notification of any new nodes added to the collection or the entire tree) and once with a subscription of type "items" (to receive all items published within the tree). However, a service SHOULD NOT allow an entity to subscribe twice to a collection node (once with a subscription depth of "1" and once with a subscription depth of "all") for the same subscription type, since two such subscriptions are unnecessary (a depth of "all" includes by definition a depth of "1"); in this case the service SHOULD return a <conflict/> error to the requesting entity.

Example 15. Service does not allow mulitple subscriptions to the same node
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='collsub1'>
  <error type='cancel'>
    <conflict xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

Depending on the nature of the node graph, a subscription type of "items" and depth of "all" may result in an extremely large number of notifications. Therefore, a service MAY disallow such a combination of subscription options, in which case it MUST return a <not-allowed/> error to the requesting entity.

Example 16. Service does not allow requested options
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='collsub1'>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

6.2 Retrieving Items on Collection Nodes

When an entity requests items on a collection node the service SHOULD return the items on any leaf nodes associated with it subject to the access model of the collection node.

6.2.1 Request

Example 17. Subscriber requests all items on a collection
<iq type='get'
    from='francisco@denmark.lit/barracks'
    to='pubsub.shakespeare.lit'
    id='items1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <items node='blogs'/>
  </pubsub>
</iq>

6.2.2 Success Case

When a collection contains multiple nodes with items it MUST return multiple <items/> elements, one per node.

Example 18. Service returns items on leaf nodes
<iq type='result'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='items1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <items node='Romeoance'>
      <item id='368866411b877c30064a5f62b917cffe'>
        ...
      </item>
    </items>
    <items node='Julliennui'>
      <item id='3300659945416e274474e469a1f0154c'>
        ...
      </item>
    </items>
  </pubsub>
</iq>

6.2.3 Error Cases

Depending on the nature of the node graph it may be expensive to allow item retrieval from a collection node. Therefore the service MAY disallow item retrieval via collection nodes, in which case it MUST return a <feature-not-implemented/> error to the requesting entity.

Example 19. Service cannot fulfil request
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='items1'>
  <error type='cancel'>
    <feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

7. Owner Use Cases

7.1 Create a New Collection Node

As specified in Publish-Subscribe (XEP-0060) [1] the default value for "pubsub#node_type" SHOULD be "leaf". To create a new collection node, the requesting entity MUST include a Data Form containing a "pubsub#node_type" field whose <value/> element contains "collection".

7.1.1 Request

Example 20. Entity requests a new collection node
<iq type='set'
    from='francisco@denmark.lit/barracks'
    to='pubsub.shakespeare.lit'
    id='create3'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <create node='announcements'/>
    <configure>
      <x xmlns='jabber:x:data' type='submit'>
        <field var='FORM_TYPE' type='hidden'>
          <value>http://jabber.org/protocol/pubsub#node_config</value>
        </field>
        <field var='pubsub#node_type'><value>collection</value></field>
      </x>
    </configure>
  </pubsub>
</iq>

7.1.2 Success Case

Example 21. Service responds with success
<iq type='result'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='create3'/>

7.1.3 Error Cases

In addition to the errors already defined for leaf node creation, there are several reasons why the collection node creation request might fail:

  1. The service does not support collection nodes.
  2. The service does not support creation of collection nodes.
  3. The requesting entity does not have sufficient privileges to create collection nodes.

These error cases are described more fully in the following sections.

7.1.3.1 Collection Nodes Unsupported

If the service does not support collection nodes, it MUST respond with a <feature-not-implemented/> error, specifying a pubsub-specific error condition of <unsupported/> and a feature of "collections".

Example 22. Service does not support collection nodes
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='create3'>
  <error type='cancel'>
    <feature-not-implemented xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <unsupported xmlns='http://jabber.org/protocol/pubsub#errors'
                 feature='collections'/>
  </error>
</iq>
7.1.3.2 Collection Nodes Can't be Created

If the service supports collection nodes but does not allow new collection nodes to be created, it MUST respond with a <not-allowed/> error.

Example 23. Service does not allow creation of collection nodes
<iq type='error'
    from='hamlet@denmark.lit/elsinore'
    to='pubsub.shakespeare.lit'
    id='create3'>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>
7.1.3.3 Entity is not Authorized

If the requesting entity has insufficient privileges to create new collections, the service MUST respond with a <forbidden/> error.

Example 24. Requesting entity has insufficient privileges to create collection nodes
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='create3'>
  <error type='auth'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

7.2 Configuring a Collection Node

7.2.1 Request

In addition to the node configuration options specified in Publish-Subscribe (XEP-0060) [1], there are three additional node configuration options that a service which supports collection nodes MUST supply.

To associate the root node to the collection the <value/> element MUST be empty.

A service MUST support the "pubsub#notify_config" option (specified in Publish-Subscribe (XEP-0060) [1]) for collection nodes.

A service MAY offer some node configuration options that are specific to collection nodes and SHOULD NOT be provided in configuration forms related to leaf nodes. The following are RECOMMENDED:

Example 25. Entity configures a collection node
<iq type='set'
    from='francisco@denmark.lit/barracks'
    to='pubsub.shakespeare.lit'
    id='config1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
    <configure node='blogs'>
      <x xmlns='jabber:x:data' type='submit'>
        <field var='FORM_TYPE' type='hidden'>
          <value>http://jabber.org/protocol/pubsub#node_config</value>
        </field>
        <field var='pubsub#node_type'>
          <value>collection</value>
        </field>
        <field var='pubsub#children'>
          <value>Romeoance</value>
          <value>Julliennui</value>
        </field>
        <field var='pubsub#collection'>
          <value/>
        </field>
      </x>
    </configure>
  </pubsub>
</iq>

7.2.2 Success Case

Example 26. Service successfully updates configuration
<iq type='result'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='config1'/>

7.2.3 Error Cases

7.2.3.1 Configuring a Leaf Node with Children

Leaf nodes only contain published items and MUST NOT have any children. If an entity attempts to add children to a leaf node (either via "pubsub#children" on the leaf node or "pubsub#collection" on another node) the service MUST return a <not-allowed/> error with a pubsub-specific error condition of <invalid-options/>.

Example 27. Attempt to add a leaf node as the parent of another node
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='config1'>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <invalid-options xmlns='http://jabber.org/protocol/pubsub#errors'/>
  </error>
</iq>
7.2.3.2 Entity is not Authorized

If the requesting entity is not authorized to add the node to a collection then the service MUST return a <forbidden/> error.

Example 28. Entity is not authorized to add node to a collection
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='config1'>
  <error type='cancel'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>
7.2.3.3 Maximum Number of Children Exceeded

If the configuration would exceed the maximum number of children allowed on a node, either because the node's "pubsub#children" exceeds its own "pubsub#children_max" value or because adding this node to a parent via "pubsub#collection" would exceed the parent's "pubsub#children_max" value, the service MUST return a <not-allowed/> error with a pubsub-specific error condition of <max-nodes-exceeded/>.

Example 29. Node would contain too many children
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='config1'>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <max-nodes-exceeded xmlns='http://jabber.org/protocol/pubsub#errors'/>
  </error>
</iq>
7.2.3.4 Changing Node Type to Leaf

The service MUST NOT allow the node type to be changed from collection to leaf. If it is attempted the service MUST return a <not-allowed/> error, specifying a pubsub-specific error condition of <invalid-options/>

Example 30. Attempt to change node type
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='config1'>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <invalid-options xmlns='http://jabber.org/protocol/pubsub#errors'/>
  </error>
</iq>

Note: Changing the node type leaf to collection is permissible under conditions specified in Changing Node Type to Collection.

7.2.3.5 Creating a Cycle in the Collection

The service MUST NOT allow a cycle to be created in the node graph (e.g., node A to B to C to A). If an entity attempts to submit a configuration that would create a cycle the service MUST return a <not-allowed/> error, specifying a pubsub-specific error condition of <invalid-options/>.

Example 31. Cycle created in node graph
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='config1'>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <invalid-options xmlns='http://jabber.org/protocol/pubsub#errors'/>
  </error>
</iq>

7.2.4 Changing Node Type to Collection

A node type can be changed from leaf to collection (but not vice versa). If the node type is changed from leaf to collection and there are items associated with the node, the service MUST purge the node of all items (with or without notifying the subscribers).

7.3 Request Default Node Configuration Options

As specified in Publish-Subscribe (XEP-0060) [1] a service can support retrieval of default node configuration, allowing an entity to request information about the default node configuration.

7.3.1 Request

To get the node options for a collection node, the entity MUST send an empty <default/> element to the service with no NodeID. The entity SHOULD include the optional 'type' attribute with value 'collection'. In response, the service SHOULD return the default node options.

Example 32. Entity requests default collection node configuration options
<iq type='get'
    from='hamlet@denmark.lit/elsinore'
    to='pubsub.shakespeare.lit'
    id='def1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
    <default type='collection'/>
  </pubsub>
</iq>

7.3.2 Success Case

If no error occurs, the service MUST return the default node configuration options.

Example 33. Service responds with default node configuration options
<iq type='result'
    from='pubsub.shakespeare.lit'
    to='hamlet@denmark.lit/elsinore'
    id='def1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
    <default>
      <x xmlns='jabber:x:data' type='form'>
        <field var='FORM_TYPE' type='hidden'>
          <value>http://jabber.org/protocol/pubsub#node_config</value>
        </field>
        <field var='pubsub#title' type='text-single'
               label='A friendly name for the node'/>
        <field var='pubsub#description' type='text-single'
             label='A description of the node'/>
        <field var='pubsub#node_type'
               type='list-single'
               label='Whether the node is a leaf (default) or a collection'>
          <option label='The node is a leaf node (default)'>
            <value>leaf</value>
          </option>
          <option label='The node is a collection node'>
            <value>collection</value>
          </option>
          <value>collection</value>
        </field>
        <field var='pubsub#collection'
               type='text-multi'
               label='The collections of which this node is a child'/>
        <field var='pubsub#children'
               type='text-multi'
               label='The nodes of which this node is a parent'/>
        <field var='pubsub#children_association_policy'
               type='list-single'>
          <option label='Only the owners of this node may associate other nodes to this collection'>
            owners
          </option>
          <option label='Only those on the children association whitelist may associate other nodes to this collection'>
            whitelist
          </option>
          <option label='Anyone may associate nodes with this collection'>
            all
          </option>
          <value>owner</value>
        </field>
        <field var='pubsub#children_association_whitelist'
               type='jid-multi'
               label='JIDs who can associate nodes to this collection'/>
        <field var='pubsub#children_max'
               type='text-single'
               label='The maximum number of children for this collection'/>
        <field var='pubsub#deliver_notifications' type='boolean'
               label='Deliver event notifications'>
          <value>true</value>
        </field>
        <field var='pubsub#notify_config' type='boolean'
               label='Notify subscribers when the node configuration changes'>
          <value>0</value>
        </field>
        <field var='pubsub#notify_delete' type='boolean'
               label='Notify subscribers when the node is deleted'>
          <value>0</value>
        </field>
        <field var='pubsub#notify_sub' type='boolean'
               label='Notify owners about new subscribers and unsubscribes'>
          <value>0</value>
        </field>
        <field var='pubsub#subscribe' type='boolean'
               label='Whether to allow subscriptions'>
          <value>1</value>
        </field>
        <field var='pubsub#access_model' type='list-single'
               label='Specify the subscriber model'>
          <option><value>authorize</value></option>
          <option><value>open</value></option>
          <option><value>presence</value></option>
          <option><value>roster</value></option>
          <option><value>whitelist</value></option>
          <value>open</value>
        </field>
      </x>
    </default>
  </pubsub>
</iq>

7.3.3 Error Cases

There are several reasons why the default node configuration options request might fail. These cases are defined in Publish-Subscribe (XEP-0060) [1].

7.4 Deleting a Collection Node

7.4.1 Request

If a service supports collection node creation it MUST support collection node deletion.

Example 34. Owner attempts to delete a collection node
<iq type='set'
    from='francisco@denmark.lit/barracks'
    to='pubsub.shakespeare.lit'
    id='delete1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
    <delete node='blogs'/>
  </pubsub>
</iq>

7.4.2 Success Case

If no error occurs, the service MUST inform the owner of success.

Example 35. Collection node was deleted
<iq type='result'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='delete1'/>

7.4.3 Error Cases

7.4.3.1 Deleting the Root Node

If the requesting entity attempts to delete the root node, the service MUST return a <not-allowed/> error.

Example 36. Node is the root
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='delete1'>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

7.5 Associating a Node to a Collection

7.5.1 Request

A service MAY allow collection nodes to have children associated with them without changing the rest of the configuration. If the service allows this an entity can send and <associate/> element with a 'node' attribute that contains the child node within a <collection/> element that posesses a 'node' attribute containing the parent node to the service.

Example 37. Entity requests node association
<iq type='set'
    from='francisco@denmark.lit/barracks'
    to='pubsub.shakespeare.lit'
    id='assoc1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
    <collection node='some-collection'>
      <associate node='new-child-node'/>
    </collection>
  </pubsub>
</iq>

7.5.2 Success Case

If the service allows the node association then it MUST confirm the association with an empty result.

Example 38. Service associates the node
<iq type='result'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit'
    id='assoc1'/>

7.5.3 Error Cases

7.5.3.1 Entity is not Authorized
Example 39. Entity is not authorized to associate the node
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='assoc1'>
  <error type='cancel'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>
7.5.3.2 Maximum Number of Children Exceeded

If the configuration would exceed the maximum number of children allowed on a node, either because the node's "pubsub#children" exceeds its own "pubsub#children_max" value or because adding this node to a parent via "pubsub#collection" would exceed the parent's "pubsub#children_max" value, the service MUST return a <not-allowed/> error with a pubsub-specific error condition of <max-nodes-exceeded/>.

Example 40. Node would contain too many children
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='assoc1'>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <max-nodes-exceeded xmlns='http://jabber.org/protocol/pubsub#errors'/>
  </error>
</iq>
7.5.3.3 Creating a Cycle in the Collection

The service MUST NOT allow a cycle to be created in the node graph (e.g., node A to B to C to A). If an entity attempts to submit a configuration that would create a cycle the service MUST return a <not-allowed/> error, specifying a pubsub-specific error condition of <invalid-options/>.

Example 41. Cycle created in node graph
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='assoc1'>
  <error type='cancel'>
    <not-allowed xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
    <invalid-options xmlns='http://jabber.org/protocol/pubsub#errors'/>
  </error>
</iq>

7.6 Dissociating a Node from a Collection

7.6.1 Request

A service MAY allow collection nodes to have children dissociated from them without changing the rest of the configuration. If the service allows this an entity can send and <dissociate/> element with a 'node' attribute that contains the child node within a <collection/> element that posesses a 'node' attribute containing the parent node to the service.

Example 42. Entity requests node dissociation
<iq type='set'
    from='francisco@denmark.lit/barracks'
    to='pubsub.shakespeare.lit'
    id='dissoc1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub#owner'>
    <collection node='some-collection'>
      <dissociate node='old-child-node'/>
    </collection>
  </pubsub>
</iq>

7.6.2 Success Case

If the service allows the node dissociation then it MUST confirm the association with an empty result.

Example 43. Service dissociates the node
<iq type='result'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit'
    id='dissoc1'/>

7.6.3 Error Cases

7.6.3.1 Node is not Associated

If a dissociation is requested between two nodes that are not already associated then the service MUST return a <bad-request/> error.

Example 44. Node is not associated
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit'
    id='dissoc1'>
  <error type='modify'>
    <bad-request xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>
7.6.3.2 Entity is not Authorized
Example 45. Entity is not authorized to dissociate the node
<iq type='error'
    from='pubsub.shakespeare.lit'
    to='francisco@denmark.lit/barracks'
    id='dissoc1'>
  <error type='cancel'>
    <forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>
  </error>
</iq>

8. Implementation Notes

8.1 Root Node

To provide a starting point for service discovery a service SHOULD support a root node. A root node represents the node belonging to a given service and MUST be identified by the lack of a node identifier (i.e., the address of the pubsub service itself, such as "pubsub.shakespeare.lit"). Because the root node is owned by the service itself an entity SHOULD NOT be allowed create, delete, or configure the root node.

If a node is created or configured without any parents specified, a service MAY automatically associate otherwise orphaned nodes directly to the root node. If a service automatically associates a node with the root it MUST reflect that in the node configuration data form.

Example 46. Entity subscribes to the root node
<iq type='set'
    from='francisco@denmark.lit/barracks'
    to='pubsub.shakespeare.lit'
    id='root1'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <subscribe jid='francisco@denmark.lit'/>
  </pubsub>
</iq>

8.2 Handling Collection Node Deletion

Deletion of collection nodes can have a number of side effects due to implementation. Depending on the nature of the collection any of the following MAY happen when a collection node is deleted:

8.3 Updating Node Configuration When Associating or Dissociating Nodes

Node configuration MUST always reflect the current state of the node graph. Because node configuration contains both a pointer to its parents as well as its children an update to a primary node's "pubsub#collection" value will change the value of the secondary node's "pubsub#children" value, and vice-versa. A service MAY send a notification of the configuration change on the secondary node to subscribers if "pubsub#notify_config" is enabled on the secondary node.

9. Feature Summary

This section summarizes the features described herein, specifies the appropriate requirements level for each feature (REQUIRED, RECOMMENDED, or OPTIONAL), and provides cross-references to the section of this document in which each feature is described.

Note: The feature names are all of the form "http://jabber.org/protocol/pubsub#name", where "name" is the text specified in the first column below.

Table 1: Service Discovery Features
Name Description Support Section
collections Collection nodes are supported. OPTIONAL
multi-collection A single leaf node can be associated with multiple collections. OPTIONAL

10. Security Considerations

10.1 Access Models

Collection nodes can be used to associate almost any node within the service, but only the access model of the collection node itself is used to determine what an entity is allowed to see. Therefore care should be taken that nodes are not linked in such a way as to leak private data (e.g., from a "closed" leaf node through an "open" collection) unless that behavior is specifically desired.

11. IANA Considerations

This document requires no interaction with the Internet Assigned Numbers Authority (IANA) [6].

12. XMPP Registrar Considerations

Note: These options are in addition to the standard options described in Publish-Subscribe (XEP-0060) [1] and related XEPs.

12.1 Service Discovery Features

<var>
  <name>pubsub#collections</name>
  <desc>Support for collection nodes</desc>
  <doc>XEP-0248</doc>
</var>
<var>
  <name>pubsub#multi-collections</name>
  <desc>Support for multiple collections on a node</desc>
  <doc>XEP-0248</doc>
</var>

12.2 Field Standardization

12.2.1 pubsub#subscribe_options FORM_TYPE

<form_type>
  <name>http://jabber.org/protocol/pubsub#subscribe_options</name>
  <doc>XEP-0248</doc>
  <desc>Options for collection node subscription</desc>
  <field
      var='pubsub#subscription_depth'
      type='text-single'>
      label='How far to traverse the node graph for notifications'/>
  <field
      var='pubsub#subscription_type'
      type='list-single'>
    <option label='Receive notification of items only'>
      items
    </option>
    <option label='Receive notification of nodes only'>
      nodes
    </option>
    <option label='Receive notification of items and nodes'>
      all
    </option>
  </field>
</form_type>

12.2.2 pubsub#node_config FORM_TYPE

<form_type>
  <name>http://jabber.org/protocol/pubsub#node_config</name>
  <doc>XEP-0248</doc>
  <desc>Options for collection node configuration</desc>
  <field
      var='pubsub#node_type'
      type='list-single'>
    <option label='The node contains items'>
      leaf
    </option>
    <option label='The node contains other nodes'>
      collection
    </option>
  </field>
  <field
      var='pubsub#collection'
      type='text-multi'
      label='The collections of which this node is a child'/>
  <field
      var='pubsub#children'
      type='text-multi'
      label='The nodes of which this node is a parent'/>
  <field
      var='pubsub#children_association_policy'
      type='list-single'>
    <option label='Only the owners of this node may associate other nodes to this collection'>
      owners
    </option>
    <option label='Only those on the children association whitelist may associate other nodes to this collection'>
      whitelist
    </option>
    <option label='Anyone may associate nodes with this collection'>
      all
    </option>
  </field>
  <field
      var='pubsub#children_association_whitelist'
      type='jid-multi'
      label='JIDs who can associate nodes to this collection'/>
  <field
      var='pubsub#children_max'
      type='text-single'
      label='The maximum number of children for this collection'/>
</form_type>

12.3 SHIM Headers

The XMPP Registrar includes "Collection" in its registry of SHIM headers (see <https://xmpp.org/registrar/shim.html>). The registry submission is as follows:

<header>
  <name>Collection</name>
  <desc>The node of subscription that sent a notification</desc>
  <doc>XEP-0248</doc>
</header>

12.4 Service Discovery Category/Type

In its registry of Service Discovery identities (see <https://xmpp.org/registrar/disco-categories.html>) the XMPP Registrar includes a specific types within the "pubsub" category:

Table 2: Service Discovery Types in Pubsub Category
collection A pubsub node of the "collection" type as described in XEP-0248.

The registry submission is as follows:

<category>
  <name>pubsub</name>
  <desc>Services and nodes that adhere to XEP-0060.</desc>
  <type>
    <name>collection</name>
    <desc>A pubsub node of the "collection" type.</desc>
    <doc>XEP-0248</doc>
  </type>
</category>

13. XML Schema

REQUIRED.

14. Acknowledgements

Many thanks to Dave Cridland for his feedback and advice.


Appendices

Appendix A: Document Information

Series
XEP
Number
0248
Publisher
XMPP Standards Foundation
Status
Deferred
Type
Standards Track
Version
0.5.0
Last Updated
2025-09-11
Approving Body
XMPP Council
Dependencies
XMPP Core, XEP-0060
Supersedes
None
Superseded By
None
Short Name
NOT_YET_ASSIGNED
Source Control
HTML

This document in other formats: XML  PDF

Appendix B: Author Information

Peter Saint-Andre
Email
stpeter@stpeter.im
JabberID
stpeter@jabber.org
URI
https://stpeter.im/
Ralph Meijer
Email
ralphm@ik.nu
JabberID
ralphm@ik.nu
Brian Cully
Email
bjc@kublai.com
JabberID
bjc@kublai.com

Copyright

This XMPP Extension Protocol is copyright © 1999 – 2024 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. ##

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 from, out of, or in connection with the Specification or the implementation, deployment, or other use of 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 can be found at <https://xmpp.org/about/xsf/ipr-policy> or obtained by writing to XMPP Standards Foundation, P.O. Box 787, Parker, CO 80134 USA).

Visual Presentation

The HTML representation (you are looking at) is maintained by the XSF. It is based on the YAML CSS Framework, which is licensed under the terms of the CC-BY-SA 2.0 license.

Appendix D: Relation to XMPP

The Extensible Messaging and Presence Protocol (XMPP) is defined in the XMPP Core (RFC 6120) and XMPP IM (RFC 6121) 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.

Appendix E: Discussion Venue

The primary venue for discussion of XMPP Extension Protocols is the <standards@xmpp.org> discussion list.

Discussion on other xmpp.org discussion lists might also be appropriate; see <https://xmpp.org/community/> for a complete list.

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

Appendix F: Requirements Conformance

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

Appendix G: Notes

1. XEP-0060: Publish-Subscribe <https://xmpp.org/extensions/xep-0060.html>.

2. XEP-0030: Service Discovery <https://xmpp.org/extensions/xep-0030.html>.

3. XEP-0055: Jabber Search <https://xmpp.org/extensions/xep-0055.html>.

4. XEP-0131: Stanza Headers and Internet Metadata <https://xmpp.org/extensions/xep-0131.html>.

5. XEP-0004: Data Forms <https://xmpp.org/extensions/xep-0004.html>.

6. 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/>.

Appendix H: Revision History

Note: Older versions of this specification might be available at https://xmpp.org/extensions/attic/

  1. Version 0.5.0 (2025-09-11)
    gdk
  2. Version 0.4.0 (2025-09-11)

    Add section on retrieving default node configuration that's specific to a particular node type

    gdk
  3. Version 0.3.0 (2021-08-03)
    Revert change from version 0.2.1 which changed meta-data to metadata in wire protocol. That was an unintended breaking change which has now been reverted.
    rm
  4. Version 0.2.1 (2018-11-03)
    Fix a bunch of typos, batch-style.
    pep
  5. Version 0.2 (2010-09-28)

    Completely reworked from initial version. To wit:

    bjc
  6. Version 0.1 (2008-08-11)

    Initial version, split from XEP-0060.

    psa

Appendix I: Bib(La)TeX Entry

@report{saint-andre2008xep0248,
  title = {PubSub Collection Nodes},
  author = {Saint-Andre, Peter and Meijer, Ralph and Cully, Brian},
  type = {XEP},
  number = {0248},
  version = {0.5.0},
  institution = {XMPP Standards Foundation},
  url = {https://xmpp.org/extensions/xep-0248.html},
  date = {2008-08-11/2025-09-11},
}

END