diff --git a/keyserver/src/responders/link-responders.js b/keyserver/src/responders/link-responders.js
--- a/keyserver/src/responders/link-responders.js
+++ b/keyserver/src/responders/link-responders.js
@@ -1,36 +1,55 @@
 // @flow
 
-import t from 'tcomb';
+import t, { type TUnion, type TInterface } from 'tcomb';
 
 import type {
   InviteLinkVerificationRequest,
   InviteLinkVerificationResponse,
   FetchInviteLinksResponse,
 } from 'lib/types/link-types.js';
-import { tShape } from 'lib/utils/validation-utils.js';
+import { tShape, tID } from 'lib/utils/validation-utils.js';
 
 import {
   fetchPrimaryInviteLinks,
   verifyInviteLink,
 } from '../fetchers/link-fetchers.js';
 import { Viewer } from '../session/viewer.js';
-import { validateInput } from '../utils/validation-utils.js';
+import { validateInput, validateOutput } from '../utils/validation-utils.js';
 
-const inviteLinkVerificationRequestInputValidator = tShape({
-  secret: t.String,
-});
+const inviteLinkVerificationRequestInputValidator: TInterface<InviteLinkVerificationRequest> =
+  tShape({
+    secret: t.String,
+  });
+
+export const inviteLinkVerificationResponseValidator: TUnion<InviteLinkVerificationResponse> =
+  t.union([
+    tShape({
+      status: t.enums.of(['valid', 'already_joined']),
+      community: tShape({
+        name: t.String,
+        id: tID,
+      }),
+    }),
+    tShape({
+      status: t.enums.of(['invalid', 'expired']),
+    }),
+  ]);
 
 async function inviteLinkVerificationResponder(
   viewer: Viewer,
   input: any,
 ): Promise<InviteLinkVerificationResponse> {
-  const request: InviteLinkVerificationRequest = input;
-  await validateInput(
+  const request = await validateInput(
     viewer,
     inviteLinkVerificationRequestInputValidator,
-    request,
+    input,
+  );
+  const response = await verifyInviteLink(viewer, request);
+  return validateOutput(
+    viewer.platformDetails,
+    inviteLinkVerificationResponseValidator,
+    response,
   );
-  return await verifyInviteLink(viewer, request);
 }
 
 async function fetchPrimaryInviteLinksResponder(
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
@@ -14,6 +14,7 @@
   restoreEntryResponseValidator,
 } from './entry-responders.js';
 import { getSessionPublicKeysResponseValidator } from './keys-responders.js';
+import { inviteLinkVerificationResponseValidator } from './link-responders.js';
 import { messageReportCreationResultValidator } from './message-report-responder.js';
 import {
   fetchMessageInfosResponseValidator,
@@ -938,3 +939,17 @@
     expect(reportCreationResponseValidator.is({})).toBe(false);
   });
 });
+
+describe('link responders', () => {
+  it('should validate invite link verification response', () => {
+    const response = {
+      status: 'already_joined',
+      community: {
+        name: 'name',
+        id: '123',
+      },
+    };
+    expect(inviteLinkVerificationResponseValidator.is(response)).toBe(true);
+    expect(inviteLinkVerificationResponseValidator.is({})).toBe(false);
+  });
+});