diff --git a/lib/shared/dm-ops/change-thread-read-status-spec.js b/lib/shared/dm-ops/change-thread-read-status-spec.js
new file mode 100644
--- /dev/null
+++ b/lib/shared/dm-ops/change-thread-read-status-spec.js
@@ -0,0 +1,54 @@
+// @flow
+
+import uuid from 'uuid';
+
+import type {
+  DMOperationSpec,
+  ProcessDMOperationUtilities,
+} from './dm-op-spec';
+import type { DMChangeThreadReadStatusOperation } from '../../types/dm-ops';
+import { updateTypes } from '../../types/update-types-enum.js';
+
+const changeThreadReadStatusSpec: DMOperationSpec<DMChangeThreadReadStatusOperation> =
+  Object.freeze({
+    processDMOperation: async (
+      dmOperation: DMChangeThreadReadStatusOperation,
+    ) => {
+      const { threadID, unread, time } = dmOperation;
+      const updateInfos = [
+        {
+          type: updateTypes.UPDATE_THREAD_READ_STATUS,
+          id: uuid.v4(),
+          time,
+          threadID,
+          unread,
+        },
+      ];
+      return {
+        rawMessageInfos: [],
+        updateInfos,
+      };
+    },
+    canBeProcessed(
+      dmOperation: DMChangeThreadReadStatusOperation,
+      viewerID: string,
+      utilities: ProcessDMOperationUtilities,
+    ) {
+      const { creatorID, threadID } = dmOperation;
+      if (viewerID !== creatorID) {
+        return { isProcessingPossible: false, reason: { type: 'invalid' } };
+      }
+
+      if (!utilities.threadInfos[threadID]) {
+        return {
+          isProcessingPossible: false,
+          reason: { type: 'missing_thread', threadID },
+        };
+      }
+
+      return { isProcessingPossible: true };
+    },
+    supportsAutoRetry: true,
+  });
+
+export { changeThreadReadStatusSpec };
diff --git a/lib/shared/dm-ops/dm-op-specs.js b/lib/shared/dm-ops/dm-op-specs.js
--- a/lib/shared/dm-ops/dm-op-specs.js
+++ b/lib/shared/dm-ops/dm-op-specs.js
@@ -2,6 +2,7 @@
 
 import { addMembersSpec } from './add-members-spec.js';
 import { addViewerToThreadMembersSpec } from './add-viewer-to-thread-members-spec.js';
+import { changeThreadReadStatusSpec } from './change-thread-read-status-spec.js';
 import { changeThreadSettingsSpec } from './change-thread-settings-spec.js';
 import { changeThreadSubscriptionSpec } from './change-thread-subscription.js';
 import { createSidebarSpec } from './create-sidebar-spec.js';
@@ -30,4 +31,5 @@
   [dmOperationTypes.REMOVE_MEMBERS]: removeMembersSpec,
   [dmOperationTypes.CHANGE_THREAD_SETTINGS]: changeThreadSettingsSpec,
   [dmOperationTypes.CHANGE_THREAD_SUBSCRIPTION]: changeThreadSubscriptionSpec,
+  [dmOperationTypes.CHANGE_THREAD_READ_STATUS]: changeThreadReadStatusSpec,
 });
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
@@ -33,6 +33,7 @@
   REMOVE_MEMBERS: 'remove_members',
   CHANGE_THREAD_SETTINGS: 'change_thread_settings',
   CHANGE_THREAD_SUBSCRIPTION: 'change_thread_subscription',
+  CHANGE_THREAD_READ_STATUS: 'change_thread_read_status',
 });
 export type DMOperationType = $Values<typeof dmOperationTypes>;
 
@@ -323,6 +324,22 @@
     subscription: threadSubscriptionValidator,
   });
 
+export type DMChangeThreadReadStatusOperation = {
+  +type: 'change_thread_read_status',
+  +time: number,
+  +threadID: string,
+  +creatorID: string,
+  +unread: boolean,
+};
+export const dmChangeThreadReadStatusOperationValidator: TInterface<DMChangeThreadReadStatusOperation> =
+  tShape<DMChangeThreadReadStatusOperation>({
+    type: tString(dmOperationTypes.CHANGE_THREAD_READ_STATUS),
+    time: t.Number,
+    threadID: t.String,
+    creatorID: tUserID,
+    unread: t.Boolean,
+  });
+
 export type DMOperation =
   | DMCreateThreadOperation
   | DMCreateSidebarOperation
@@ -335,7 +352,8 @@
   | DMLeaveThreadOperation
   | DMRemoveMembersOperation
   | DMChangeThreadSettingsOperation
-  | DMChangeThreadSubscriptionOperation;
+  | DMChangeThreadSubscriptionOperation
+  | DMChangeThreadReadStatusOperation;
 export const dmOperationValidator: TUnion<DMOperation> = t.union([
   dmCreateThreadOperationValidator,
   dmCreateSidebarOperationValidator,
@@ -349,6 +367,7 @@
   dmRemoveMembersOperationValidator,
   dmChangeThreadSettingsOperationValidator,
   dmChangeThreadSubscriptionOperationValidator,
+  dmChangeThreadReadStatusOperationValidator,
 ]);
 
 export type DMOperationResult = {