diff --git a/lib/shared/dm-ops/create-sidebar-spec.js b/lib/shared/dm-ops/create-sidebar-spec.js
--- a/lib/shared/dm-ops/create-sidebar-spec.js
+++ b/lib/shared/dm-ops/create-sidebar-spec.js
@@ -7,7 +7,6 @@
   DMOperationSpec,
   ProcessDMOperationUtilities,
 } from './dm-op-spec.js';
-import { isInvalidSidebarSource } from '../../shared/message-utils.js';
 import type { DMCreateSidebarOperation } from '../../types/dm-ops.js';
 import { messageTypes } from '../../types/message-types-enum.js';
 import {
@@ -16,6 +15,7 @@
 } from '../../types/message-types.js';
 import { threadTypes } from '../../types/thread-types-enum.js';
 import { updateTypes } from '../../types/update-types-enum.js';
+import { isInvalidSidebarSource } from '../message-utils.js';
 
 const createSidebarSpec: DMOperationSpec<DMCreateSidebarOperation> =
   Object.freeze({
@@ -46,11 +46,10 @@
         roleID,
         creatorID,
         viewerID,
+        sourceMessageID,
+        containingThreadID: parentThreadID,
       });
 
-      rawThreadInfo.sourceMessageID = sourceMessageID;
-      rawThreadInfo.containingThreadID = parentThreadID;
-
       const sourceMessage = await utilities.fetchMessage(sourceMessageID);
       if (!sourceMessage) {
         throw new Error(
diff --git a/lib/shared/dm-ops/create-thread-spec.js b/lib/shared/dm-ops/create-thread-spec.js
--- a/lib/shared/dm-ops/create-thread-spec.js
+++ b/lib/shared/dm-ops/create-thread-spec.js
@@ -9,8 +9,10 @@
   makePermissionsBlob,
   getThickThreadRolePermissionsBlob,
 } from '../../permissions/thread-permissions.js';
-import { generatePendingThreadColor } from '../../shared/color-utils.js';
-import type { DMCreateThreadOperation } from '../../types/dm-ops.js';
+import type {
+  CreateThickRawThreadInfoInput,
+  DMCreateThreadOperation,
+} from '../../types/dm-ops.js';
 import { messageTypes } from '../../types/message-types-enum.js';
 import {
   type RawMessageInfo,
@@ -24,20 +26,10 @@
   minimallyEncodeThreadCurrentUserInfo,
 } from '../../types/minimally-encoded-thread-permissions-types.js';
 import { joinThreadSubscription } from '../../types/subscription-types.js';
-import type { ThickThreadType } from '../../types/thread-types-enum.js';
 import type { ThickMemberInfo } from '../../types/thread-types.js';
 import { updateTypes } from '../../types/update-types-enum.js';
+import { generatePendingThreadColor } from '../color-utils.js';
 
-type CreateThickRawThreadInfoInput = {
-  +threadID: string,
-  +threadType: ThickThreadType,
-  +creationTime: number,
-  +parentThreadID?: ?string,
-  +allMemberIDs: $ReadOnlyArray<string>,
-  +roleID: string,
-  +creatorID: string,
-  +viewerID: string,
-};
 type MutableThickRawThreadInfo = { ...ThickRawThreadInfo };
 function createThickRawThreadInfo(
   input: CreateThickRawThreadInfoInput,
@@ -51,9 +43,17 @@
     roleID,
     creatorID,
     viewerID,
+    name,
+    avatar,
+    description,
+    color,
+    containingThreadID,
+    sourceMessageID,
+    repliesCount,
+    pinnedCount,
   } = input;
 
-  const color = generatePendingThreadColor(allMemberIDs);
+  const threadColor = color ?? generatePendingThreadColor(allMemberIDs);
 
   const rolePermissions = getThickThreadRolePermissionsBlob(threadType);
   const membershipPermissions = getAllThreadPermissions(
@@ -70,12 +70,12 @@
     specialRole: specialRoles.DEFAULT_ROLE,
   };
 
-  return {
+  const newThread: MutableThickRawThreadInfo = {
     thick: true,
     minimallyEncoded: true,
     id: threadID,
     type: threadType,
-    color,
+    color: threadColor,
     creationTime,
     parentThreadID,
     members: allMemberIDs.map(memberID =>
@@ -96,8 +96,19 @@
       subscription: joinThreadSubscription,
       unread: creatorID !== viewerID,
     }),
-    repliesCount: 0,
+    repliesCount: repliesCount ?? 0,
+    name,
+    avatar,
+    description,
+    containingThreadID,
   };
+  if (sourceMessageID) {
+    newThread.sourceMessageID = sourceMessageID;
+  }
+  if (pinnedCount) {
+    newThread.pinnedCount = pinnedCount;
+  }
+  return newThread;
 }
 
 const createThreadSpec: DMOperationSpec<DMCreateThreadOperation> =
diff --git a/lib/types/dm-ops.js b/lib/types/dm-ops.js
--- a/lib/types/dm-ops.js
+++ b/lib/types/dm-ops.js
@@ -3,11 +3,13 @@
 import type { TInterface, TUnion } from 'tcomb';
 import t from 'tcomb';
 
+import type { ClientAvatar } from './avatar-types.js';
 import type { RawMessageInfo } from './message-types.js';
 import type { OutboundP2PMessage } from './sqlite-types.js';
 import {
   type NonSidebarThickThreadType,
   nonSidebarThickThreadTypes,
+  type ThickThreadType,
 } from './thread-types-enum.js';
 import type { ClientUpdateInfo } from './update-types.js';
 import { values } from '../utils/objects.js';
@@ -22,6 +24,25 @@
 });
 export type DMOperationType = $Values<typeof dmOperationTypes>;
 
+export type CreateThickRawThreadInfoInput = {
+  +threadID: string,
+  +threadType: ThickThreadType,
+  +creationTime: number,
+  +parentThreadID?: ?string,
+  +allMemberIDs: $ReadOnlyArray<string>,
+  +roleID: string,
+  +creatorID: string,
+  +viewerID: string,
+  +name?: ?string,
+  +avatar?: ?ClientAvatar,
+  +description?: ?string,
+  +color?: ?string,
+  +containingThreadID?: ?string,
+  +sourceMessageID?: ?string,
+  +repliesCount?: ?number,
+  +pinnedCount?: ?number,
+};
+
 export type DMCreateThreadOperation = {
   +type: 'create_thread',
   +threadID: string,