diff --git a/keyserver/src/endpoints.js b/keyserver/src/endpoints.js
--- a/keyserver/src/endpoints.js
+++ b/keyserver/src/endpoints.js
@@ -53,6 +53,15 @@
   roleModificationResultValidator,
   roleDeletionResultValidator,
 } from 'lib/types/validators/thread-validators.js';
+import {
+  logInResponseValidator,
+  registerResponseValidator,
+  logOutResponseValidator,
+  claimUsernameResponseValidator,
+  subscriptionUpdateResponseValidator,
+  updateUserAvatarResponderValidator,
+} from 'lib/types/validators/user-validators.js';
+import { versionResponseValidator } from 'lib/types/validators/version-validators.js';
 import { updateUserAvatarRequestValidator } from 'lib/utils/avatar-utils.js';
 
 import {
@@ -183,30 +192,21 @@
   policyAcknowledgmentResponder,
   updateUserAvatarResponder,
   registerRequestInputValidator,
-  registerResponseValidator,
-  logOutResponseValidator,
   logInRequestInputValidator,
-  logInResponseValidator,
   policyAcknowledgmentRequestInputValidator,
   accountUpdateInputValidator,
   resetPasswordRequestInputValidator,
   siweAuthRequestInputValidator,
   subscriptionUpdateRequestInputValidator,
-  subscriptionUpdateResponseValidator,
   updatePasswordRequestInputValidator,
-  updateUserAvatarResponderValidator,
   updateUserSettingsInputValidator,
   claimUsernameResponder,
-  claimUsernameResponseValidator,
 } from './responders/user-responders.js';
 import {
   codeVerificationResponder,
   codeVerificationRequestInputValidator,
 } from './responders/verification-responders.js';
-import {
-  versionResponder,
-  versionResponseValidator,
-} from './responders/version-responders.js';
+import { versionResponder } from './responders/version-responders.js';
 import {
   uploadMediaMetadataResponder,
   uploadDeletionResponder,
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
@@ -35,13 +35,13 @@
   threadJoinResultValidator,
   toggleMessagePinResultValidator,
 } from 'lib/types/validators/thread-validators.js';
-
-import { roleChangeRequestInputValidator } from './thread-responders.js';
 import {
   logInResponseValidator,
   registerResponseValidator,
   logOutResponseValidator,
-} from './user-responders.js';
+} from 'lib/types/validators/user-validators.js';
+
+import { roleChangeRequestInputValidator } from './thread-responders.js';
 
 describe('user responder validators', () => {
   it('should validate logout response', () => {
diff --git a/keyserver/src/responders/user-responders.js b/keyserver/src/responders/user-responders.js
--- a/keyserver/src/responders/user-responders.js
+++ b/keyserver/src/responders/user-responders.js
@@ -4,16 +4,14 @@
 import invariant from 'invariant';
 import { getRustAPI } from 'rust-node-addon';
 import { SiweErrorType, SiweMessage } from 'siwe';
-import t, { type TInterface, type TUnion, type TEnums } from 'tcomb';
+import t, { type TInterface } from 'tcomb';
 import bcrypt from 'twin-bcrypt';
 
 import {
   baseLegalPolicies,
   policies,
-  policyTypeValidator,
   policyTypes,
 } from 'lib/facts/policies.js';
-import { mixedRawThreadInfoValidator } from 'lib/permissions/minimally-encoded-raw-thread-info-validators.js';
 import { hasMinCodeVersion } from 'lib/shared/version-utils.js';
 import type {
   KeyserverAuthRequest,
@@ -35,7 +33,6 @@
 } from 'lib/types/account-types.js';
 import {
   type ClientAvatar,
-  clientAvatarValidator,
   type UpdateUserAvatarResponse,
   type UpdateUserAvatarRequest,
 } from 'lib/types/avatar-types.js';
@@ -51,14 +48,9 @@
 } from 'lib/types/device-types';
 import {
   type CalendarQuery,
-  rawEntryInfoValidator,
   type FetchEntryInfosBase,
 } from 'lib/types/entry-types.js';
-import {
-  defaultNumberPerThread,
-  rawMessageInfoValidator,
-  messageTruncationStatusesValidator,
-} from 'lib/types/message-types.js';
+import { defaultNumberPerThread } from 'lib/types/message-types.js';
 import type {
   SIWEAuthRequest,
   SIWEMessage,
@@ -67,15 +59,8 @@
 import {
   type SubscriptionUpdateRequest,
   type SubscriptionUpdateResponse,
-  threadSubscriptionValidator,
 } from 'lib/types/subscription-types.js';
-import { createUpdatesResultValidator } from 'lib/types/update-types.js';
-import {
-  type PasswordUpdate,
-  loggedOutUserInfoValidator,
-  loggedInUserInfoValidator,
-  userInfoValidator,
-} from 'lib/types/user-types.js';
+import { type PasswordUpdate } from 'lib/types/user-types.js';
 import {
   identityKeysBlobValidator,
   signedIdentityKeysBlobValidator,
@@ -158,11 +143,6 @@
     }),
   });
 
-export const subscriptionUpdateResponseValidator: TInterface<SubscriptionUpdateResponse> =
-  tShape<SubscriptionUpdateResponse>({
-    threadSubscription: threadSubscriptionValidator,
-  });
-
 async function userSubscriptionUpdateResponder(
   viewer: Viewer,
   request: SubscriptionUpdateRequest,
@@ -205,11 +185,6 @@
   await checkAndSendPasswordResetEmail(request);
 }
 
-export const logOutResponseValidator: TInterface<LogOutResponse> =
-  tShape<LogOutResponse>({
-    currentUserInfo: loggedOutUserInfoValidator,
-  });
-
 async function logOutResponder(viewer: Viewer): Promise<LogOutResponse> {
   if (viewer.loggedIn) {
     const [anonymousViewerData] = await Promise.all([
@@ -261,17 +236,6 @@
     initialNotificationsEncryptedMessage: t.maybe(t.String),
   });
 
-export const registerResponseValidator: TInterface<RegisterResponse> =
-  tShape<RegisterResponse>({
-    id: t.String,
-    rawMessageInfos: t.list(rawMessageInfoValidator),
-    currentUserInfo: loggedInUserInfoValidator,
-    cookieChange: tShape({
-      threadInfos: t.dict(tID, mixedRawThreadInfoValidator),
-      userInfos: t.list(userInfoValidator),
-    }),
-  });
-
 async function accountCreationResponder(
   viewer: Viewer,
   request: RegisterRequest,
@@ -486,21 +450,6 @@
     initialNotificationsEncryptedMessage: t.maybe(t.String),
   });
 
-export const logInResponseValidator: TInterface<ServerLogInResponse> =
-  tShape<ServerLogInResponse>({
-    currentUserInfo: loggedInUserInfoValidator,
-    rawMessageInfos: t.list(rawMessageInfoValidator),
-    truncationStatuses: messageTruncationStatusesValidator,
-    userInfos: t.list(userInfoValidator),
-    rawEntryInfos: t.maybe(t.list(rawEntryInfoValidator)),
-    serverTime: t.Number,
-    cookieChange: tShape({
-      threadInfos: t.dict(tID, mixedRawThreadInfoValidator),
-      userInfos: t.list(userInfoValidator),
-    }),
-    notAcknowledgedPolicies: t.maybe(t.list<TEnums>(policyTypeValidator)),
-  });
-
 async function logInResponder(
   viewer: Viewer,
   request: LogInRequest,
@@ -925,18 +874,6 @@
   await viewerAcknowledgmentUpdater(viewer, request.policy);
 }
 
-export const updateUserAvatarResponseValidator: TInterface<UpdateUserAvatarResponse> =
-  tShape<UpdateUserAvatarResponse>({
-    updates: createUpdatesResultValidator,
-  });
-
-export const updateUserAvatarResponderValidator: TUnion<
-  ?ClientAvatar | UpdateUserAvatarResponse,
-> = t.union([
-  t.maybe(clientAvatarValidator),
-  updateUserAvatarResponseValidator,
-]);
-
 async function updateUserAvatarResponder(
   viewer: Viewer,
   request: UpdateUserAvatarRequest,
@@ -944,12 +881,6 @@
   return await updateUserAvatar(viewer, request);
 }
 
-export const claimUsernameResponseValidator: TInterface<ClaimUsernameResponse> =
-  tShape<ClaimUsernameResponse>({
-    message: t.String,
-    signature: t.String,
-  });
-
 async function claimUsernameResponder(
   viewer: Viewer,
 ): Promise<ClaimUsernameResponse> {
diff --git a/keyserver/src/responders/version-responders.js b/keyserver/src/responders/version-responders.js
--- a/keyserver/src/responders/version-responders.js
+++ b/keyserver/src/responders/version-responders.js
@@ -1,22 +1,12 @@
 // @flow
 
-import t, { type TInterface } from 'tcomb';
-
 import type { VersionResponse } from 'lib/types/device-types.js';
 import { getCommConfig } from 'lib/utils/comm-config.js';
-import { tShape } from 'lib/utils/validation-utils.js';
 
 import type { UserCredentials } from '../user/checks.js';
 import { verifyUserLoggedIn } from '../user/login.js';
 import { keyserverCodeVersion } from '../version.js';
 
-export const versionResponseValidator: TInterface<VersionResponse> =
-  tShape<VersionResponse>({
-    codeVersion: t.Number,
-    ownerUsername: t.maybe(t.String),
-    ownerID: t.maybe(t.String),
-  });
-
 async function versionResponder(): Promise<VersionResponse> {
   const userInfoPromise = getCommConfig<UserCredentials>({
     folder: 'secrets',
diff --git a/lib/types/validators/user-validators.js b/lib/types/validators/user-validators.js
new file mode 100644
--- /dev/null
+++ b/lib/types/validators/user-validators.js
@@ -0,0 +1,87 @@
+// @flow
+
+import t, { type TInterface, type TUnion, type TEnums } from 'tcomb';
+
+import { policyTypeValidator } from '../../facts/policies.js';
+import { mixedRawThreadInfoValidator } from '../../permissions/minimally-encoded-raw-thread-info-validators.js';
+import { tShape, tID } from '../../utils/validation-utils.js';
+import type {
+  LogOutResponse,
+  RegisterResponse,
+  ServerLogInResponse,
+  ClaimUsernameResponse,
+} from '../account-types.js';
+import {
+  type ClientAvatar,
+  clientAvatarValidator,
+  type UpdateUserAvatarResponse,
+} from '../avatar-types.js';
+import { rawEntryInfoValidator } from '../entry-types.js';
+import {
+  rawMessageInfoValidator,
+  messageTruncationStatusesValidator,
+} from '../message-types.js';
+import {
+  type SubscriptionUpdateResponse,
+  threadSubscriptionValidator,
+} from '../subscription-types.js';
+import { createUpdatesResultValidator } from '../update-types.js';
+import {
+  loggedOutUserInfoValidator,
+  loggedInUserInfoValidator,
+  userInfoValidator,
+} from '../user-types.js';
+
+export const registerResponseValidator: TInterface<RegisterResponse> =
+  tShape<RegisterResponse>({
+    id: t.String,
+    rawMessageInfos: t.list(rawMessageInfoValidator),
+    currentUserInfo: loggedInUserInfoValidator,
+    cookieChange: tShape({
+      threadInfos: t.dict(tID, mixedRawThreadInfoValidator),
+      userInfos: t.list(userInfoValidator),
+    }),
+  });
+
+export const logOutResponseValidator: TInterface<LogOutResponse> =
+  tShape<LogOutResponse>({
+    currentUserInfo: loggedOutUserInfoValidator,
+  });
+
+export const logInResponseValidator: TInterface<ServerLogInResponse> =
+  tShape<ServerLogInResponse>({
+    currentUserInfo: loggedInUserInfoValidator,
+    rawMessageInfos: t.list(rawMessageInfoValidator),
+    truncationStatuses: messageTruncationStatusesValidator,
+    userInfos: t.list(userInfoValidator),
+    rawEntryInfos: t.maybe(t.list(rawEntryInfoValidator)),
+    serverTime: t.Number,
+    cookieChange: tShape({
+      threadInfos: t.dict(tID, mixedRawThreadInfoValidator),
+      userInfos: t.list(userInfoValidator),
+    }),
+    notAcknowledgedPolicies: t.maybe(t.list<TEnums>(policyTypeValidator)),
+  });
+
+export const subscriptionUpdateResponseValidator: TInterface<SubscriptionUpdateResponse> =
+  tShape<SubscriptionUpdateResponse>({
+    threadSubscription: threadSubscriptionValidator,
+  });
+
+export const updateUserAvatarResponseValidator: TInterface<UpdateUserAvatarResponse> =
+  tShape<UpdateUserAvatarResponse>({
+    updates: createUpdatesResultValidator,
+  });
+
+export const updateUserAvatarResponderValidator: TUnion<
+  ?ClientAvatar | UpdateUserAvatarResponse,
+> = t.union([
+  t.maybe(clientAvatarValidator),
+  updateUserAvatarResponseValidator,
+]);
+
+export const claimUsernameResponseValidator: TInterface<ClaimUsernameResponse> =
+  tShape<ClaimUsernameResponse>({
+    message: t.String,
+    signature: t.String,
+  });
diff --git a/lib/types/validators/version-validators.js b/lib/types/validators/version-validators.js
new file mode 100644
--- /dev/null
+++ b/lib/types/validators/version-validators.js
@@ -0,0 +1,13 @@
+// @flow
+
+import t, { type TInterface } from 'tcomb';
+
+import { tShape } from '../../utils/validation-utils.js';
+import type { VersionResponse } from '../device-types.js';
+
+export const versionResponseValidator: TInterface<VersionResponse> =
+  tShape<VersionResponse>({
+    codeVersion: t.Number,
+    ownerUsername: t.maybe(t.String),
+    ownerID: t.maybe(t.String),
+  });