diff --git a/blah-types/src/lib.rs b/blah-types/src/lib.rs
index 496a82c..2f9f3c9 100644
--- a/blah-types/src/lib.rs
+++ b/blah-types/src/lib.rs
@@ -353,9 +353,6 @@ pub enum CreateRoomPayload {
 #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
 pub struct CreateGroup {
     pub attrs: RoomAttrs,
-    /// The initial member list. Besides invariants of `RoomMemberList`, this also must include the
-    /// room creator themselves, with the highest permission (-1).
-    pub members: RoomMemberList,
     pub title: String,
 }
 
diff --git a/blahctl/src/main.rs b/blahctl/src/main.rs
index 6761d67..b309f6f 100644
--- a/blahctl/src/main.rs
+++ b/blahctl/src/main.rs
@@ -4,8 +4,8 @@ use std::{fs, io};
 
 use anyhow::{Context, Result};
 use blah_types::{
-    bitflags, get_timestamp, ChatPayload, CreateGroup, CreateRoomPayload, Id, MemberPermission,
-    RichText, RoomAttrs, RoomMember, RoomMemberList, ServerPermission, Signed, UserKey,
+    bitflags, get_timestamp, ChatPayload, CreateGroup, CreateRoomPayload, Id, RichText, RoomAttrs,
+    ServerPermission, Signed, UserKey,
 };
 use ed25519_dalek::pkcs8::spki::der::pem::LineEnding;
 use ed25519_dalek::pkcs8::{DecodePrivateKey, DecodePublicKey, EncodePrivateKey, EncodePublicKey};
@@ -220,12 +220,6 @@ async fn main_api(api_url: Url, command: ApiCommand) -> Result<()> {
             let payload = CreateRoomPayload::Group(CreateGroup {
                 attrs: attrs.unwrap_or_default(),
                 title,
-                // The CLI does not support passing multiple members because `User` itself is a
-                // disjoint arg-group.
-                members: RoomMemberList(vec![RoomMember {
-                    permission: MemberPermission::ALL,
-                    user: UserKey(key.verifying_key().to_bytes()),
-                }]),
             });
             let payload = Signed::sign(&key, get_timestamp(), &mut OsRng, payload)?;
 
diff --git a/blahd/src/lib.rs b/blahd/src/lib.rs
index 60f45fe..7368ec9 100644
--- a/blahd/src/lib.rs
+++ b/blahd/src/lib.rs
@@ -363,44 +363,34 @@ async fn room_create_group(
         ));
     }
 
-    let members = &op.members.0;
-    if !members
-        .iter()
-        .any(|m| m.user == user && m.permission == MemberPermission::ALL)
-    {
-        return Err(error_response!(
-            StatusCode::BAD_REQUEST,
-            "deserialization",
-            "invalid initial members",
-        ));
-    }
-
-    let mut conn = st.db.get();
-    let Some(true) = conn
+    let conn = st.db.get();
+    let (uid, _perm) = conn
         .query_row(
             r"
-            SELECT `permission`
+            SELECT `uid`, `permission`
             FROM `user`
             WHERE `userkey` = ?
             ",
             params![user],
             |row| {
-                let perm = row.get::<_, ServerPermission>("permission")?;
-                Ok(perm.contains(ServerPermission::CREATE_ROOM))
+                Ok((
+                    row.get::<_, i64>("uid")?,
+                    row.get::<_, ServerPermission>("permission")?,
+                ))
             },
         )
         .optional()?
-    else {
-        return Err(error_response!(
-            StatusCode::FORBIDDEN,
-            "permission_denied",
-            "user does not have permission to create room",
-        ));
-    };
+        .filter(|(_, perm)| perm.contains(ServerPermission::CREATE_ROOM))
+        .ok_or_else(|| {
+            error_response!(
+                StatusCode::FORBIDDEN,
+                "permission_denied",
+                "the user does not exist or does not have permission to create room",
+            )
+        })?;
 
-    let txn = conn.transaction()?;
     let rid = Id::gen();
-    txn.execute(
+    conn.execute(
         r"
         INSERT INTO `room` (`rid`, `title`, `attrs`)
         VALUES (:rid, :title, :attrs)
@@ -411,32 +401,17 @@ async fn room_create_group(
             ":attrs": op.attrs,
         },
     )?;
-    let mut insert_user = txn.prepare(
-        r"
-        INSERT INTO `user` (`userkey`)
-        VALUES (?)
-        ON CONFLICT (`userkey`) DO NOTHING
-        ",
-    )?;
-    let mut insert_member = txn.prepare(
+    conn.execute(
         r"
         INSERT INTO `room_member` (`rid`, `uid`, `permission`)
-        SELECT :rid, `uid`, :permission
-        FROM `user`
-        WHERE `userkey` = :userkey
+        VALUES (:rid, :uid, :perm)
         ",
-    )?;
-    for member in members {
-        insert_user.execute(params![member.user])?;
-        insert_member.execute(named_params! {
+        named_params! {
             ":rid": rid,
-            ":userkey": member.user,
-            ":permission": member.permission,
-        })?;
-    }
-    drop(insert_member);
-    drop(insert_user);
-    txn.commit()?;
+            ":uid": uid,
+            ":perm": MemberPermission::ALL,
+        },
+    )?;
 
     Ok(Json(rid))
 }
diff --git a/blahd/tests/webapi.rs b/blahd/tests/webapi.rs
index 3d1602c..126a261 100644
--- a/blahd/tests/webapi.rs
+++ b/blahd/tests/webapi.rs
@@ -8,8 +8,8 @@ use std::sync::{Arc, LazyLock};
 use anyhow::Result;
 use blah_types::{
     get_timestamp, AuthPayload, ChatPayload, CreateGroup, CreatePeerChat, CreateRoomPayload, Id,
-    MemberPermission, RichText, RoomAdminOp, RoomAdminPayload, RoomAttrs, RoomMember,
-    RoomMemberList, RoomMetadata, ServerPermission, Signed, SignedChatMsg, UserKey, WithMsgId,
+    MemberPermission, RichText, RoomAdminOp, RoomAdminPayload, RoomAttrs, RoomMetadata,
+    ServerPermission, Signed, SignedChatMsg, UserKey, WithMsgId,
 };
 use blahd::{ApiError, AppState, Database, RoomList, RoomMsgs};
 use ed25519_dalek::SigningKey;
@@ -120,10 +120,6 @@ impl Server {
             &mut *self.rng.borrow_mut(),
             CreateRoomPayload::Group(CreateGroup {
                 attrs,
-                members: RoomMemberList(vec![RoomMember {
-                    permission: MemberPermission::ALL,
-                    user: UserKey(key.verifying_key().to_bytes()),
-                }]),
                 title: title.to_string(),
             }),
         );
diff --git a/docs/webapi.yaml b/docs/webapi.yaml
index 59c18ad..48caed3 100644
--- a/docs/webapi.yaml
+++ b/docs/webapi.yaml
@@ -612,16 +612,6 @@ components:
                       const: 'create_room'
                     title:
                       type: string
-                    members:
-                      type: array
-                      items:
-                        type: object
-                        properties:
-                          user:
-                            type: string
-                          permission:
-                            type: integer
-                            format: int64
                 - type: object
                   properties:
                     typ: