diff --git a/docs/specification.rst b/docs/specification.rst
index 9a494a4c0f..23c6b12091 100644
--- a/docs/specification.rst
+++ b/docs/specification.rst
@@ -417,7 +417,7 @@ State events can be sent by ``PUT`` ing to ``/rooms/<room id>/state/<event type>
These events will be overwritten if ``<room id>``, ``<event type>`` and ``<state key>`` all match.
If the state event has no ``state_key``, it can be omitted from the path. These requests
**cannot use transaction IDs** like other ``PUT`` paths because they cannot be differentiated
-from the ``state key``. Furthermore, ``POST`` is unsupported on state paths. Valid requests
+from the ``state_key``. Furthermore, ``POST`` is unsupported on state paths. Valid requests
look like::
PUT /rooms/!roomid:domain/state/m.example.event
@@ -440,7 +440,7 @@ Care should be taken to avoid setting the wrong ``state key``::
{ "key" : "with '11' as the state key, but was probably intended to be a txnId" }
The ``state_key`` is often used to store state about individual users, by using the user ID as the
-value. For example::
+``state_key`` value. For example::
PUT /rooms/!roomid:domain/state/m.favorite.animal.event/%40my_user%3Adomain.com
{ "animal" : "cat", "reason": "fluffy" }
@@ -471,7 +471,8 @@ Syncing rooms
-------------
When a client logs in, they may have a list of rooms which they have already joined. These rooms
may also have a list of events associated with them. The purpose of 'syncing' is to present the
-current room and event information in a convenient, compact manner. There are two APIs provided:
+current room and event information in a convenient, compact manner. The events returned are not
+limited to room events; presence events will also be returned. There are two APIs provided:
- ``/initialSync`` : A global sync which will present room and event information for all rooms
the user has joined.
@@ -482,10 +483,40 @@ current room and event information in a convenient, compact manner. There are tw
- TODO: JSON response format for both types
- TODO: when would you use global? when would you use scoped?
-Getting grouped state events for a room
----------------------------------------
-- ``/members`` and ``/messages`` and the event types they return. Spec JSON response format.
-- ``/state`` and it returns ALL THE THINGS.
+Getting events for a room
+-------------------------
+There are several APIs provided to ``GET`` events for a room:
+
+``/rooms/<room id>/state/<event type>/<state key>``
+ Description:
+ Get the state event identified.
+ Response format:
+ A JSON object representing the state event **content**.
+ Example:
+ ``/rooms/!room:domain.com/state/m.room.name`` returns ``{ "name": "Room name" }``
+
+``/rooms/<room id>/state``
+ Description:
+ Get all state events for a room.
+ Response format:
+ ``[ { state event }, { state event }, ... ]``
+ Example:
+ TODO
+
+
+``/rooms/<room id>/members``
+ Description:
+ Get all ``m.room.member`` state events.
+ Response format:
+ ``{ "start": "token", "end": "token", "chunk": [ { m.room.member event }, ... ] }``
+ Example:
+ TODO
+
+
+
+- ``/rooms/<room id>/messages`` : Get all ``m.room.message`` events.
+- ``/rooms/<room id>/initialSync`` : Get all relevant events for a room.
+
Room Events
===========
@@ -493,24 +524,109 @@ Room Events
This specification outlines several standard event types, all of which are
prefixed with ``m.``
-State messages
---------------
-- m.room.name
-- m.room.topic
-- m.room.member
-- m.room.config
-- m.room.invite_join
+``m.room.name``
+ Summary:
+ Set the human-readable name for the room.
+ Type:
+ State event
+ JSON format:
+ ``{ "name" : "string" }``
+ Example:
+ ``{ "name" : "My Room" }``
+ Description:
+ A room has an opaque room ID which is not human-friendly to read. A room alias is
+ human-friendly, but not all rooms have room aliases. The room name is a human-friendly
+ string designed to be displayed to the end-user. The room name is not *unique*, as
+ multiple rooms can have the same room name set. The room name can also be set when
+ creating a room using ``/createRoom`` with the ``name`` key.
+
+``m.room.topic``
+ Summary:
+ Set a topic for the room.
+ Type:
+ State event
+ JSON format:
+ ``{ "topic" : "string" }``
+ Example:
+ ``{ "topic" : "Welcome to the real world." }``
+ Description:
+ A topic is a short message detailing what is currently being discussed in the room.
+ It can also be used as a way to display extra information about the room, which may
+ not be suitable for the room name.
-What are they, when are they used, what do they contain, how should they be used.
-Link back to explanatory sections (e.g. invite/join/leave sections for m.room.member)
+``m.room.member``
+ Summary:
+ The current membership state of a user in the room.
+ Type:
+ State event
+ JSON format:
+ ``{ "membership" : "enum[ invite|join|leave|ban ]" }``
+ Example:
+ ``{ "membership" : "join" }``
+ Description:
+ Adjusts the membership state for a user in a room. It is preferable to use the
+ membership APIs (``/rooms/<room id>/invite`` etc) when performing membership actions
+ rather than adjusting the state directly as there are a restricted set of valid
+ transformations. For example, user A cannot force user B to join a room, and trying
+ to force this state change directly will fail. See the "Rooms" section for how to
+ use the membership APIs.
+
+``m.room.config``
+ Summary:
+ The room config.
+ Type:
+ State event
+ JSON format:
+ TODO
+ Example:
+ TODO
+ Description:
+ TODO
-Non-state messages
-------------------
-- m.room.message
-- m.room.message.feedback (and compressed format)
-- voip?
+``m.room.invite_join``
+ Summary:
+ TODO.
+ Type:
+ State event
+ JSON format:
+ TODO
+ Example:
+ TODO
+ Description:
+ TODO
+
+``m.room.message``
+ Summary:
+ A message.
+ Type:
+ Non-state event
+ JSON format:
+ ``{ "msgtype": "string" }``
+ Example:
+ ``{ "msgtype": "m.text", "body": "Testing" }``
+ Description:
+ This event is used when sending messages in a room. Messages are not limited to be text.
+ The ``msgtype`` key outlines the type of message, e.g. text, audio, image, video, etc.
+ Whilst not required, the ``body`` key SHOULD be used with every kind of ``msgtype`` as
+ a fallback mechanism when a client cannot render the message. For more information on
+ the types of messages which can be sent, see "m.room.message msgtypes".
+
+``m.room.message.feedback``
+ Summary:
+ A receipt for a message.
+ Type:
+ Non-state event
+ JSON format:
+ ``{ "type": "enum [ delivered|read ]", "target_event_id": "string" }``
+ Example:
+ ``{ "type": "delivered", "target_event_id": "e3b2icys" }``
+ Description:
+ Feedback events are events sent to acknowledge a message in some way. There are two
+ supported acknowledgements: ``delivered`` (sent when the event has been received) and
+ ``read`` (sent when the event has been observed by the end-user). The ``target_event_id``
+ should reference the ``m.room.message`` event being acknowledged.
-What are they, when are they used, what do they contain, how should they be used
+- voip?
m.room.message msgtypes
-----------------------
@@ -636,6 +752,14 @@ client devices they have connected. The home server should synchronise this
status choice among multiple devices to ensure the user gets a consistent
experience.
+In addition, the server maintains a timestamp of the last time it saw an active
+action from the user; either sending a message to a room, or changing presence
+state from a lower to a higher level of availability (thus: changing state from
+``unavailable`` to ``online`` will count as an action for being active, whereas
+in the other direction will not). This timestamp is presented via a key called
+``last_active_ago``, which gives the relative number of miliseconds since the
+message is generated/emitted, that the user was last seen active.
+
Idle Time
---------
As well as the basic ``presence`` field, the presence information can also show
|