Rooms & Events

Event Model

Every action in Matrix is an event. Events form a Directed Acyclic Graph (DAG) within each room.

Event Types

TypePurposeExample
m.room.createRoom creationFirst event in every room
m.room.memberMembership changesjoin, leave, invite, ban
m.room.nameRoom display name{"name": "General Chat"}
m.room.topicRoom topic{"topic": "Discussion"}
m.room.messageChat messages{"msgtype": "m.text", "body": "Hello"}
m.room.stateRoom stateCustom state events
m.room.redactionEvent redactionRemove event content
m.relates_toEvent relationsThreads, annotations, edits

Event Structure

{
  "event_id": "$abc123",
  "room_id": "!room:localhost",
  "sender": "@alice:localhost",
  "type": "m.room.message",
  "state_key": null,
  "content": {
    "msgtype": "m.text",
    "body": "Hello, Matrix!"
  },
  "origin_server_ts": 1625000000000,
  "unsigned": {
    "age": 12345
  }
}

Room Lifecycle

Creation

POST /createRoom → Creates m.room.create event
                 → Creates m.room.member (creator joins)
                 → Creates m.room.power_levels
                 → Creates m.room.history_visibility

Room creation extracts creation_content.type to support:

  • Regular rooms (default)
  • Spaces (m.space)

State Events

State events have a state_key and represent the room's current state. Only the latest event with a given (type, state_key) pair is considered "current".

Membership

The m.room.member event tracks user membership:

MembershipMeaning
joinUser is in the room
inviteUser has been invited
leaveUser has left or been kicked
banUser has been banned

Membership changes trigger:

  • Device list change notifications (device_lists.changed in /sync)
  • Room member count updates
  • Power level recalculations

Event Relations

Events can relate to each other via m.relates_to:

Relation TypePurposeExample
m.threadThreaded conversationsReply in a thread
m.annotationReactions/emoji👍 on a message
m.replaceEditsEdit a sent message
m.referenceReferencesReference another event

Relations are persisted in the event_relations table and queried via the /relations API.

Redaction

Redaction removes event content while preserving the event wrapper. Redacted events retain their event_id, room_id, sender, and type but content is cleared except for a whitelist of allowed keys per event type.

Space Hierarchy

Spaces are rooms with creation_content.type = "m.space". Child rooms are linked via m.space.child state events. The hierarchy API walks this tree to return room structures:

GET /hierarchy/{roomId} → {
  rooms: [
    { room_id, name, topic, num_joined_members, room_type }
  ]
}

The hierarchy walk is cycle-safe and permission-filtered (only rooms the requester can see are returned).