XEP-0503: Server-side spaces

Abstract
This document defines an XMPP protocol to cluster several groupchat rooms together.
Authors
  • Nicolas Cedilnik
  • Timothée Jaussoin
Copyright
© 2025 – 2025 XMPP Standards Foundation. SEE LEGAL NOTICES.
Status

Experimental

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 are advised to carefully consider whether it is appropriate to deploy implementations of this protocol before it advances to a status of Draft.
Type
Standards Track
Version
0.2.0 (2025-09-13)
Document Lifecycle
  1. Experimental
  2. Proposed
  3. Stable
  4. Final

1. Introduction

A single group chat room is not always enough.

In various situations, one wishes to have several rooms (or even other entities) clustered together around a common theme. For instance, large open source software projects use different rooms for user support, development, announcements (examples: Slack's workspaces, Discord's servers, Mattermost's teams, WhatsApp's communities, Matrix's spaces). For the purpose of this document, let us call such group of entities under the umbrella term "spaces".

This clustering is already possible by setting up a dedicated MUC Service (Multi-User Chat (XEP-0045) [1]) to group several rooms, but existing implementations of MUC service leave that option the administrators only. This specification proposes to use the semantics of Publish-Subscribe (XEP-0060) [2] for spaces that:

Since there are many subtle variations over the concept of spaces, this specification voluntarily does not cover access control, permissions, membership inside a space and its children entities. Similarly, it does not describe how a space holding entities hosted on several services in the federated XMPP network would work (but it does not forbid it). It aims at being a lowest common denominator for all sort of spaces to be built on.

2. Terminology

3. Node Configuration

To be effectively usable as a space, a pubsub node must be configured in the way described by the following table below. We here introduce the notion of space exposure. A space can be public, meant to be joinable by anyone; or private, meant to be joined at the discretion of the node owner.

Table 1: Pubsub node configuration for any type of space
field requirement value exposure
pubsub#type MUST urn:xmpp:spaces:0 any
pubsub#notify_retract MUST true any
pubsub#persist_items MUST true any
pubsub#purge_offline MUST false any
pubsub#notify_sub SHOULD true any
pubsub#notify_config SHOULD true any
pubsub#notify_delete SHOULD true any
pubsub#publish_model SHOULD NOT open any
pubsub#access_model MUST open public
pubsub#access_model MUST authorize or whitelist private

NB: this specification is made to be fully compatible with Publish-Subscribe (XEP-0060) [2] without special server support. Ideally, additional functionality, yet to be described in subsequent specifications, would allow:

4. Discovering support

In order to act as a space service, a pubsub service MUST implement and advertise in its disco#info (Service Discovery (XEP-0030) [3]) the following features described in Publish-Subscribe (XEP-0060) [2] (prepended by http://jabber.org/protocol/pubsub#):

For better usability, it SHOULD also implement:

5. Protocol

5.1 Fetching spaces from a spaces service

Fetching the list of spaces hosted on a spaces service is done via a disco#items (Service Discovery (XEP-0030) [3]) request directed at the pubsub service JID. If supported by the server and/or if the pubsub component holds pubsub nodes that are not spaces, PubSub Type Filtering (XEP-0462) [4] support might come in handy.

Example 1. Querying the list of spaces
<iq type='get'
    from='emacs-user@megacorp.example.com/cool-client'
    to='megacorp-pubsub.example.com'
    id='spaces-items'>
  <query xmlns='http://jabber.org/protocol/disco#items'>
    <!-- Optional filter, if supported -->
    <filter xmlns='urn:xmpp:pubsub-filter:0'>
      <x xmlns='jabber:x:data' type='submit'>
        <field var='FORM_TYPE' type='hidden'>
          <value>urn:xmpp:pubsub-filter:0</value>
        </field>
        <field type='list-multi' var='included-types'>
          <value>urn:xmpp:spaces:0</value>
          <value/>
        </field>
      </x>
    </filter>
  </query>
</iq>
Example 2. Space Service responds with the list of spaces it hosts
<iq type='result'
    to='emacs-user@megacorp.example.com/cool-client'
    from='megacorp-pubsub.example.com'
    id='spaces-items'>
  <item jid='megacorp-pubsub.example.com'
        node='dev'
        name='The developers corner'/>
  <item jid='megacorp-pubsub.example.com'
        node='sales'
        name='Sales team'/>
  <item jid='megacorp-pubsub.example.com'
        node='management'
        name='The bosses lounge'/>
</iq>

5.2 Fetching the metadata associated to a space

Getting more information about a specific space relies on the standard pubsub mechanism to do so, i.e., a disco#info request directed at the space node.

If the spaces service supports Pubsub Extended Discovery (XEP-0499) [5] it could be used to reduce the number of roundtrips, by fetching metadata along with with the disco#items request of the previous section.

Example 3. Querying a space metadata
<iq type='get'
    from='emacs-user@megacorp.example.com/cool-client'
    to='megacorp-pubsub.example.com'
    id='space-metadata'>
  <query xmlns='http://jabber.org/protocol/disco#info'
         node='dev'/>
</iq>
Example 4. Space service responds with space metadata
<iq type='result'
    from='megacorp-pubsub.example.com'
    to='emacs-user@megacorp.example.com/cool-client'
    id='space-metadata'>
  <query xmlns='http://jabber.org/protocol/disco#info'
         node='dev'>
    <identity category='pubsub' type='leaf'/>
    <feature var='http://jabber.org/protocol/pubsub'/>
    <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#type'>
        <value>urn:xmpp:spaces:0</value>
      </field>
      <field var='pubsub#creator' label='Node creator' type='jid-single'>
        <value>lead-dev@megacorp.example.com</value>
      </field>
      <field var='pubsub#title'>
        <value>The developers corner</value>
      </field>
      <field var='pubsub#owner' label='Node owners' type='jid-multi'>
        <value>lead-dev@megacorp.example.com</value>
        <value>lead-dev-friend@megacorp.example.com</value>
      </field>
      <!-- other fields of the pubsub#meta-data FORM_TYPE !-->
    </x>
  </query>
</iq>

5.3 Joining a space

Joining a space is equivalent to subscribing to a pubsub node, as described in Publish-Subscribe (XEP-0060) [2]. If the pubsub service supports Pubsub Extended Subscriptions (XEP-0497) [6], clients SHOULD also subscribe to the metadata updates of this node. After a successful join, a client may decide to use Pubsub Subscription (XEP-0330) [7] or Pubsub Public Subscriptions (XEP-0465) [8] to advertise its subscriptions.

5.4 Discovering the content of a space

Discovering the children of a space uses the pubsub/items (Publish-Subscribe (XEP-0060) [2]) query directed a the node. The items can represent different entities, wrapped in appropriate elements. Chat rooms SHOULD be wrapped in PEP Native Bookmarks (XEP-0402) [9], which extensibility allows adding additional information that are useful for client to adapt their user interface, e.g. specifying that a given MUC is a Multiparty Jingle (XEP-0272) [10], or that its access is restricted to a specific subset of members of the space. Pubsub nodes SHOULD be wrapped in Pubsub Subscription (XEP-0330) [7] <subscription> elements. Other types of entities can be present and MUST be ignored by unsupporting clients.

Example 5. Querying space for its content
<iq type='get'
    from='emacs-user@megacorp.example.com/cool-client'
    to='megacorp-pubsub.example.com'
    id='space-items'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <items node='dev' />
  </pubsub>
</iq>
Example 6. Space service responds with space content
<iq type='result'
    from='megacorp-pubsub.example.com'
    to='emacs-user@megacorp.example.com/cool-client'
    id='space-items'>
  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
    <items node='dev'>
      <item id='boring-software@conference.megacorp.example.com'>
        <conference xmlns='urn:xmpp:bookmarks:1'
                    name='ERP 3000'
                    autojoin='true' />
      </item>
      <item id='programming-socks@conference.megacorp.example.com'>
        <conference xmlns='urn:xmpp:bookmarks:1'
                    name='Share your best programming socks deal HERE'>
          <extensions>
            <pinned xmlns='urn:xmpp:bookmarks-pinning:0'/>
          </extensions>
        </conference>
      </item>
      <item id='editors@conference.megacorp.example.com'>
        <conference xmlns='urn:xmpp:bookmarks:1'
                    name='Settling the text editor wars'>
        </conference>
      </item>
      <item id='https://megacorp.example.com/dev-team-presentation'>
        <x xmlns='jabber:x:oob'>
          <url>https://megacorp.example.com/dev-team-presentation</url>
        </x>
      </item>
      <item id='some-hash'>
        <subscription xmlns="urn:xmpp:pubsub:subscription:0"
                      server="megacorp-pubsub.example.com"
                      node="dev-announcements" />
      </item>
      <!-- other items -->
    </items>
  </pubsub>
</iq>

According to Publish-Subscribe (XEP-0060) [2], all items of the space are returned, but Pubsub Node Relationships (XEP-0496) [11] could be used to define a more complex hierarchy of items, e.g., chat rooms restricted to the owners and not discoverable by other users.

5.5 Advertising space membership

All entities that are part of a space SHOULD advertise their parent in their disco#info and the 'urn:xmpp:spaces:0' feature. This is useful if an entity wants to advertise the "official" space it is part of, and to help discoverability of related entities. To verify that an entity is effectively part of a space it advertises, the disco#items of the advertised node can be queried.

To advertise their parent, entities SHOULD include a Data Forms (XEP-0004) [12] of type urn:xmpp:spaces:0 with a parent field of type text-single.

In the case of Multi-User Chat (XEP-0045) [1], the muc#roominfo_pubsub field SHOULD point to the space node IRI for backwards compatibility of this specification with existing MUC services implementations.

Example 7. Querying a MUC information
<iq from='emacs-user@megacorp.example.com/cool-client'
    to='programming-socks@conference.megacorp.example.com'
    type='get'>
  <query xmlns='http://jabber.org/protocol/disco#info'/>
</iq>
Example 8. MUC reply, including its parent space
<iq from='programming-socks@conference.megacorp.example.com'
    to='emacs-user@megacorp.example.com/cool-client'
    type='result'>
  <query xmlns='http://jabber.org/protocol/disco#info'>
  <!-- [...] -->
  <feature var='urn:xmpp:spaces:0'/>
  <x xmlns='jabber:x:data' type='result'>
    <field var='FORM_TYPE' type='hidden'>
      <value>urn:xmpp:spaces:0</value>
    </field>
    <field var='parent' label='Space parent''>
      <value>xmpp:megacorp-pubsub.example.com?;node=dev</value>
    </field>
  </x>
  <x xmlns='jabber:x:data' type='result'>
    <field var='FORM_TYPE' type='hidden'>
      <value>http://jabber.org/protocol/muc#roominfo</value>
    </field>
    <!-- ... -->
    <field var='muc#roominfo_pubsub' label='Associated pubsub node'>
      <value>xmpp:megacorp-pubsub.example.com?;node=dev</value>
    </field>
  </x>
</query>
</iq>

6. XMPP Registrar Considerations

6.1 Protocol Namespaces

New namespace "urn:xmpp:spaces:0"

7. Security considerations

Security considerations are related to access control, and are out of scope of this document.

8. XML Schema

No new schema is defined in this document.


Appendices

Appendix A: Document Information

Series
XEP
Number
0503
Publisher
XMPP Standards Foundation
Status
Experimental
Type
Standards Track
Version
0.2.0
Last Updated
2025-09-13
Approving Body
XMPP Council
Dependencies
XMPP Core, XMPP IM
Supersedes
None
Superseded By
None
Short Name
spaces
Source Control
HTML

This document in other formats: XML  PDF

Appendix B: Author Information

Nicolas Cedilnik
Email
nicoco@nicoco.fr
JabberID
nicoco@nicoco.fr
Timothée Jaussoin
Email
edhelas@movim.eu
JabberID
edhelas@movim.eu
URI
https://edhelas.movim.eu

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-0045: Multi-User Chat <https://xmpp.org/extensions/xep-0045.html>.

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

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

4. XEP-0462: PubSub Type Filtering <https://xmpp.org/extensions/xep-0462.html>.

5. XEP-0499: Pubsub Extended Discovery <https://xmpp.org/extensions/xep-0499.html>.

6. XEP-0497: Pubsub Extended Subscriptions <https://xmpp.org/extensions/xep-0497.html>.

7. XEP-0330: Pubsub Subscription <https://xmpp.org/extensions/xep-0330.html>.

8. XEP-0465: Pubsub Public Subscriptions <https://xmpp.org/extensions/xep-0465.html>.

9. XEP-0402: PEP Native Bookmarks <https://xmpp.org/extensions/xep-0402.html>.

10. XEP-0272: Multiparty Jingle <https://xmpp.org/extensions/xep-0272.html>.

11. XEP-0496: Pubsub Node Relationships <https://xmpp.org/extensions/xep-0496.html>.

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

Appendix H: Revision History

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

  1. Version 0.2.0 (2025-09-13)

    Rewrite using pubsub semantics.

    nc
  2. Version 0.1.0 (2025-03-11)

    Promoted to Experimental

    XEP Editor: dg
  3. Version 0.0.1 (2025-02-23)

    Initial version.

    nc

Appendix I: Bib(La)TeX Entry

@report{cedilnik2025spaces,
  title = {Server-side spaces},
  author = {Cedilnik, Nicolas and Jaussoin, Timothée},
  type = {XEP},
  number = {0503},
  version = {0.2.0},
  institution = {XMPP Standards Foundation},
  url = {https://xmpp.org/extensions/xep-0503.html},
  date = {2025-02-23/2025-09-13},
}

END