diff --git a/keyserver/src/endpoints.js b/keyserver/src/endpoints.js
--- a/keyserver/src/endpoints.js
+++ b/keyserver/src/endpoints.js
@@ -51,6 +51,7 @@
   logInResponder,
   oldPasswordUpdateResponder,
   updateUserSettingsResponder,
+  policyAcknowledgmentResponder,
 } from './responders/user-responders';
 import { codeVerificationResponder } from './responders/verification-responders';
 import { uploadDeletionResponder } from './uploads/uploads';
@@ -78,6 +79,7 @@
   leave_thread: threadLeaveResponder,
   log_in: logInResponder,
   log_out: logOutResponder,
+  policy_acknowledgment: policyAcknowledgmentResponder,
   remove_members: memberRemovalResponder,
   restore_entry: entryRestorationResponder,
   search_users: userSearchResponder,
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,6 +4,7 @@
 import t from 'tcomb';
 import bcrypt from 'twin-bcrypt';
 
+import { policies } from 'lib/facts/policies.js';
 import { hasMinCodeVersion } from 'lib/shared/version-utils';
 import type {
   ResetPasswordRequest,
@@ -15,6 +16,7 @@
   LogInRequest,
   UpdatePasswordRequest,
   UpdateUserSettingsRequest,
+  PolicyAcknowledgmentRequest,
 } from 'lib/types/account-types';
 import {
   userSettingsTypes,
@@ -63,6 +65,7 @@
   updateUserSettings,
 } from '../updaters/account-updaters';
 import { userSubscriptionUpdater } from '../updaters/user-subscription-updaters';
+import { viewerAcknowledgmentUpdater } from '../updaters/viewer-acknowledgment-updater.js';
 import { validateInput } from '../utils/validation-utils';
 import {
   entryQueryInputValidator,
@@ -328,6 +331,23 @@
   return await updateUserSettings(viewer, request);
 }
 
+const policyAcknowledgmentRequestInputValidator = tShape({
+  policy: t.maybe(t.enums.of(policies)),
+});
+
+async function policyAcknowledgmentResponder(
+  viewer: Viewer,
+  input: any,
+): Promise<void> {
+  const request: PolicyAcknowledgmentRequest = input;
+  await validateInput(
+    viewer,
+    policyAcknowledgmentRequestInputValidator,
+    request,
+  );
+  await viewerAcknowledgmentUpdater(viewer, request.policy);
+}
+
 export {
   userSubscriptionUpdateResponder,
   passwordUpdateResponder,
@@ -339,4 +359,5 @@
   logInResponder,
   oldPasswordUpdateResponder,
   updateUserSettingsResponder,
+  policyAcknowledgmentResponder,
 };
diff --git a/lib/types/account-types.js b/lib/types/account-types.js
--- a/lib/types/account-types.js
+++ b/lib/types/account-types.js
@@ -1,5 +1,6 @@
 // @flow
 
+import type { PolicyType } from '../facts/policies.js';
 import { values } from '../utils/objects';
 import type { PlatformDetails } from './device-types';
 import type {
@@ -149,6 +150,10 @@
   watchedIDs: $ReadOnlyArray<string>,
 };
 
+export type PolicyAcknowledgmentRequest = {
+  +policy: PolicyType,
+};
+
 export type EmailSubscriptionRequest = {
   +email: string,
 };
diff --git a/lib/types/endpoints.js b/lib/types/endpoints.js
--- a/lib/types/endpoints.js
+++ b/lib/types/endpoints.js
@@ -24,6 +24,7 @@
   CREATE_ACCOUNT: 'create_account',
   LOG_IN: 'log_in',
   UPDATE_PASSWORD: 'update_password',
+  POLICY_ACKNOWLEDGMENT: 'policy_acknowledgment',
 });
 type SessionChangingEndpoint = $Values<typeof sessionChangingEndpoints>;