diff --git a/include/ircd/m/room.h b/include/ircd/m/room.h
index c329cfec5..8a536d3c3 100644
--- a/include/ircd/m/room.h
+++ b/include/ircd/m/room.h
@@ -30,6 +30,8 @@ namespace ircd::m
 	bool exists(const id::room_alias &, const bool &remote = false);
 	uint version(const id::room &);
 	bool federate(const id::room &);
+	id::user::buf creator(const id::room &);
+	bool creator(const id::room &, const id::user &);
 
 	// [GET]
 	id::room room_id(const mutable_buffer &, const id::room_alias &);
diff --git a/ircd/m/room.cc b/ircd/m/room.cc
index e8f3e629a..ba84d0b8a 100644
--- a/ircd/m/room.cc
+++ b/ircd/m/room.cc
@@ -167,6 +167,49 @@ ircd::m::version(const id::room &room_id)
 	return ret;
 }
 
+bool
+ircd::m::creator(const id::room &room_id,
+                 const id::user &user_id)
+{
+	const auto creator_user_id
+	{
+		creator(room_id)
+	};
+
+	return creator_user_id == user_id;
+}
+
+ircd::m::id::user::buf
+ircd::m::creator(const id::room &room_id)
+{
+	// Query the sender field of the event to get the creator. This is for
+	// future compatibility if the content.creator field gets eliminated.
+	static const event::fetch::opts fopts
+	{
+		event::keys::include
+		{
+			"sender",
+		}
+	};
+
+	const room::state state
+	{
+		room_id, &fopts
+	};
+
+	id::user::buf ret;
+	state.get("m.room.create", "", [&ret]
+	(const m::event &event)
+	{
+		ret = user::id
+		{
+			json::get<"sender"_>(event)
+		};
+	});
+
+	return ret;
+}
+
 bool
 ircd::m::federate(const id::room &room_id)
 {