diff --git a/keyserver/src/endpoints.js b/keyserver/src/endpoints.js
--- a/keyserver/src/endpoints.js
+++ b/keyserver/src/endpoints.js
@@ -42,6 +42,17 @@
   exactUserSearchResultValidator,
   userSearchResultValidator,
 } from 'lib/types/validators/search-validators.js';
+import { siweNonceResponseValidator } from 'lib/types/validators/siwe-nonce-validators.js';
+import {
+  changeThreadSettingsResultValidator,
+  leaveThreadResultValidator,
+  newThreadResponseValidator,
+  threadFetchMediaResultValidator,
+  threadJoinResultValidator,
+  toggleMessagePinResultValidator,
+  roleModificationResultValidator,
+  roleDeletionResultValidator,
+} from 'lib/types/validators/thread-validators.js';
 import { updateUserAvatarRequestValidator } from 'lib/utils/avatar-utils.js';
 
 import {
@@ -130,10 +141,7 @@
   exactUserSearchRequestInputValidator,
   userSearchRequestInputValidator,
 } from './responders/search-responders.js';
-import {
-  siweNonceResponder,
-  siweNonceResponseValidator,
-} from './responders/siwe-nonce-responders.js';
+import { siweNonceResponder } from './responders/siwe-nonce-responders.js';
 import {
   threadDeletionResponder,
   roleUpdateResponder,
@@ -146,25 +154,17 @@
   toggleMessagePinResponder,
   roleModificationResponder,
   roleDeletionResponder,
-  leaveThreadResultValidator,
   newThreadRequestInputValidator,
-  newThreadResponseValidator,
   threadDeletionRequestInputValidator,
   joinThreadRequestInputValidator,
   leaveThreadRequestInputValidator,
   threadFetchMediaRequestInputValidator,
-  threadFetchMediaResultValidator,
-  threadJoinResultValidator,
-  changeThreadSettingsResultValidator,
   removeMembersRequestInputValidator,
   roleChangeRequestInputValidator,
   toggleMessagePinRequestInputValidator,
-  toggleMessagePinResultValidator,
   updateThreadRequestInputValidator,
   roleDeletionRequestInputValidator,
-  roleDeletionResultValidator,
   roleModificationRequestInputValidator,
-  roleModificationResultValidator,
 } from './responders/thread-responders.js';
 import {
   keyserverAuthRequestInputValidator,
diff --git a/keyserver/src/responders/responder-validators.test.js b/keyserver/src/responders/responder-validators.test.js
--- a/keyserver/src/responders/responder-validators.test.js
+++ b/keyserver/src/responders/responder-validators.test.js
@@ -26,8 +26,7 @@
 import { relationshipErrorsValidator } from 'lib/types/validators/relationship-validators.js';
 import { reportCreationResponseValidator } from 'lib/types/validators/report-validators.js';
 import { userSearchResultValidator } from 'lib/types/validators/search-validators.js';
-
-import { siweNonceResponseValidator } from './siwe-nonce-responders.js';
+import { siweNonceResponseValidator } from 'lib/types/validators/siwe-nonce-validators.js';
 import {
   changeThreadSettingsResultValidator,
   leaveThreadResultValidator,
@@ -35,8 +34,9 @@
   threadFetchMediaResultValidator,
   threadJoinResultValidator,
   toggleMessagePinResultValidator,
-  roleChangeRequestInputValidator,
-} from './thread-responders.js';
+} from 'lib/types/validators/thread-validators.js';
+
+import { roleChangeRequestInputValidator } from './thread-responders.js';
 import {
   logInResponseValidator,
   registerResponseValidator,
diff --git a/keyserver/src/responders/siwe-nonce-responders.js b/keyserver/src/responders/siwe-nonce-responders.js
--- a/keyserver/src/responders/siwe-nonce-responders.js
+++ b/keyserver/src/responders/siwe-nonce-responders.js
@@ -1,16 +1,11 @@
 // @flow
 
 import { generateNonce } from 'siwe';
-import t, { type TInterface } from 'tcomb';
 
 import type { SIWENonceResponse } from 'lib/types/siwe-types.js';
-import { tShape } from 'lib/utils/validation-utils.js';
 
 import { createSIWENonceEntry } from '../creators/siwe-nonce-creator.js';
 
-export const siweNonceResponseValidator: TInterface<SIWENonceResponse> =
-  tShape<SIWENonceResponse>({ nonce: t.String });
-
 async function siweNonceResponder(): Promise<SIWENonceResponse> {
   const generatedNonce = generateNonce();
   await createSIWENonceEntry(generatedNonce);
diff --git a/keyserver/src/responders/thread-responders.js b/keyserver/src/responders/thread-responders.js
--- a/keyserver/src/responders/thread-responders.js
+++ b/keyserver/src/responders/thread-responders.js
@@ -3,12 +3,6 @@
 import t from 'tcomb';
 import type { TInterface, TUnion } from 'tcomb';
 
-import { mixedRawThreadInfoValidator } from 'lib/permissions/minimally-encoded-raw-thread-info-validators.js';
-import { mediaValidator } from 'lib/types/media-types.js';
-import {
-  rawMessageInfoValidator,
-  messageTruncationStatusesValidator,
-} from 'lib/types/message-types.js';
 import { userSurfacedPermissionValidator } from 'lib/types/thread-permission-types.js';
 import { threadTypes } from 'lib/types/thread-types-enum.js';
 import {
@@ -32,8 +26,6 @@
   type RoleDeletionRequest,
   type RoleDeletionResult,
 } from 'lib/types/thread-types.js';
-import { serverUpdateInfoValidator } from 'lib/types/update-types.js';
-import { userInfosValidator } from 'lib/types/user-types.js';
 import { updateUserAvatarRequestValidator } from 'lib/utils/avatar-utils.js';
 import { values } from 'lib/utils/objects.js';
 import {
@@ -69,13 +61,6 @@
     accountPassword: t.maybe(tPassword),
   });
 
-export const leaveThreadResultValidator: TInterface<LeaveThreadResult> =
-  tShape<LeaveThreadResult>({
-    updatesResult: tShape({
-      newUpdates: t.list(serverUpdateInfoValidator),
-    }),
-  });
-
 async function threadDeletionResponder(
   viewer: Viewer,
   request: ThreadDeletionRequest,
@@ -96,14 +81,6 @@
     }),
   });
 
-export const changeThreadSettingsResultValidator: TInterface<ChangeThreadSettingsResult> =
-  tShape<ChangeThreadSettingsResult>({
-    newMessageInfos: t.list(rawMessageInfoValidator),
-    updatesResult: tShape({
-      newUpdates: t.list(serverUpdateInfoValidator),
-    }),
-  });
-
 async function roleUpdateResponder(
   viewer: Viewer,
   request: RoleChangeRequest,
@@ -187,16 +164,6 @@
   }),
 ]);
 
-export const newThreadResponseValidator: TInterface<NewThreadResponse> =
-  tShape<NewThreadResponse>({
-    updatesResult: tShape({
-      newUpdates: t.list(serverUpdateInfoValidator),
-    }),
-    newMessageInfos: t.list(rawMessageInfoValidator),
-    userInfos: userInfosValidator,
-    newThreadID: tID,
-  });
-
 async function threadCreationResponder(
   viewer: Viewer,
   request: ServerNewThreadRequest,
@@ -213,16 +180,6 @@
     inviteLinkSecret: t.maybe(t.String),
   });
 
-export const threadJoinResultValidator: TInterface<ThreadJoinResult> =
-  tShape<ThreadJoinResult>({
-    updatesResult: tShape({
-      newUpdates: t.list(serverUpdateInfoValidator),
-    }),
-    rawMessageInfos: t.list(rawMessageInfoValidator),
-    truncationStatuses: messageTruncationStatusesValidator,
-    userInfos: userInfosValidator,
-  });
-
 async function threadJoinResponder(
   viewer: Viewer,
   request: ServerThreadJoinRequest,
@@ -241,9 +198,6 @@
     offset: t.Number,
   });
 
-export const threadFetchMediaResultValidator: TInterface<ThreadFetchMediaResult> =
-  tShape<ThreadFetchMediaResult>({ media: t.list(mediaValidator) });
-
 async function threadFetchMediaResponder(
   viewer: Viewer,
   request: ThreadFetchMediaRequest,
@@ -257,12 +211,6 @@
     action: t.enums.of(['pin', 'unpin']),
   });
 
-export const toggleMessagePinResultValidator: TInterface<ToggleMessagePinResult> =
-  tShape<ToggleMessagePinResult>({
-    newMessageInfos: t.list(rawMessageInfoValidator),
-    threadID: tID,
-  });
-
 async function toggleMessagePinResponder(
   viewer: Viewer,
   request: ToggleMessagePinRequest,
@@ -287,14 +235,6 @@
     }),
   ]);
 
-export const roleModificationResultValidator: TInterface<RoleModificationResult> =
-  tShape<RoleModificationResult>({
-    threadInfo: t.maybe(mixedRawThreadInfoValidator),
-    updatesResult: tShape({
-      newUpdates: t.list(serverUpdateInfoValidator),
-    }),
-  });
-
 async function roleModificationResponder(
   viewer: Viewer,
   request: RoleModificationRequest,
@@ -308,14 +248,6 @@
     roleID: tID,
   });
 
-export const roleDeletionResultValidator: TInterface<RoleDeletionResult> =
-  tShape<RoleDeletionResult>({
-    threadInfo: t.maybe(mixedRawThreadInfoValidator),
-    updatesResult: tShape({
-      newUpdates: t.list(serverUpdateInfoValidator),
-    }),
-  });
-
 async function roleDeletionResponder(
   viewer: Viewer,
   request: RoleDeletionRequest,
diff --git a/lib/types/validators/siwe-nonce-validators.js b/lib/types/validators/siwe-nonce-validators.js
new file mode 100644
--- /dev/null
+++ b/lib/types/validators/siwe-nonce-validators.js
@@ -0,0 +1,9 @@
+// @flow
+
+import t, { type TInterface } from 'tcomb';
+
+import { tShape } from '../../utils/validation-utils.js';
+import type { SIWENonceResponse } from '../siwe-types.js';
+
+export const siweNonceResponseValidator: TInterface<SIWENonceResponse> =
+  tShape<SIWENonceResponse>({ nonce: t.String });
diff --git a/lib/types/validators/thread-validators.js b/lib/types/validators/thread-validators.js
new file mode 100644
--- /dev/null
+++ b/lib/types/validators/thread-validators.js
@@ -0,0 +1,84 @@
+// @flow
+
+import t from 'tcomb';
+import type { TInterface } from 'tcomb';
+
+import { mixedRawThreadInfoValidator } from '../../permissions/minimally-encoded-raw-thread-info-validators.js';
+import { tShape, tID } from '../../utils/validation-utils.js';
+import { mediaValidator } from '../media-types.js';
+import {
+  rawMessageInfoValidator,
+  messageTruncationStatusesValidator,
+} from '../message-types.js';
+import {
+  type ChangeThreadSettingsResult,
+  type LeaveThreadResult,
+  type NewThreadResponse,
+  type ThreadJoinResult,
+  type ThreadFetchMediaResult,
+  type ToggleMessagePinResult,
+  type RoleModificationResult,
+  type RoleDeletionResult,
+} from '../thread-types.js';
+import { serverUpdateInfoValidator } from '../update-types.js';
+import { userInfosValidator } from '../user-types.js';
+
+export const leaveThreadResultValidator: TInterface<LeaveThreadResult> =
+  tShape<LeaveThreadResult>({
+    updatesResult: tShape({
+      newUpdates: t.list(serverUpdateInfoValidator),
+    }),
+  });
+
+export const changeThreadSettingsResultValidator: TInterface<ChangeThreadSettingsResult> =
+  tShape<ChangeThreadSettingsResult>({
+    newMessageInfos: t.list(rawMessageInfoValidator),
+    updatesResult: tShape({
+      newUpdates: t.list(serverUpdateInfoValidator),
+    }),
+  });
+
+export const newThreadResponseValidator: TInterface<NewThreadResponse> =
+  tShape<NewThreadResponse>({
+    updatesResult: tShape({
+      newUpdates: t.list(serverUpdateInfoValidator),
+    }),
+    newMessageInfos: t.list(rawMessageInfoValidator),
+    userInfos: userInfosValidator,
+    newThreadID: tID,
+  });
+
+export const threadJoinResultValidator: TInterface<ThreadJoinResult> =
+  tShape<ThreadJoinResult>({
+    updatesResult: tShape({
+      newUpdates: t.list(serverUpdateInfoValidator),
+    }),
+    rawMessageInfos: t.list(rawMessageInfoValidator),
+    truncationStatuses: messageTruncationStatusesValidator,
+    userInfos: userInfosValidator,
+  });
+
+export const threadFetchMediaResultValidator: TInterface<ThreadFetchMediaResult> =
+  tShape<ThreadFetchMediaResult>({ media: t.list(mediaValidator) });
+
+export const toggleMessagePinResultValidator: TInterface<ToggleMessagePinResult> =
+  tShape<ToggleMessagePinResult>({
+    newMessageInfos: t.list(rawMessageInfoValidator),
+    threadID: tID,
+  });
+
+export const roleModificationResultValidator: TInterface<RoleModificationResult> =
+  tShape<RoleModificationResult>({
+    threadInfo: t.maybe(mixedRawThreadInfoValidator),
+    updatesResult: tShape({
+      newUpdates: t.list(serverUpdateInfoValidator),
+    }),
+  });
+
+export const roleDeletionResultValidator: TInterface<RoleDeletionResult> =
+  tShape<RoleDeletionResult>({
+    threadInfo: t.maybe(mixedRawThreadInfoValidator),
+    updatesResult: tShape({
+      newUpdates: t.list(serverUpdateInfoValidator),
+    }),
+  });