diff --git a/packages/component-helper-service/src/services/User.js b/packages/component-helper-service/src/services/User.js
index 97821f164f7fe0af918f88c97c28c7163024721a..39ad3356cfb10e2ca78660403187bed70094f564 100644
--- a/packages/component-helper-service/src/services/User.js
+++ b/packages/component-helper-service/src/services/User.js
@@ -28,6 +28,12 @@ class User {
       handlingEditor: role === 'handlingEditor',
       invitationToken: role === 'reviewer' ? uuid.v4() : '',
       isActive: true,
+      notifications: {
+        email: {
+          system: true,
+          user: true,
+        },
+      },
     }
 
     let newUser = new UserModel(userBody)
diff --git a/packages/component-mail-service/src/Mail.js b/packages/component-mail-service/src/Mail.js
index cb3181bd26ca3b95305fdf8222022b01b3789a22..0c8c9319d0d3ef16e67e2c2c53f6db21e78a94bc 100644
--- a/packages/component-mail-service/src/Mail.js
+++ b/packages/component-mail-service/src/Mail.js
@@ -6,6 +6,7 @@ const confirmSignUp = config.get('confirm-signup.url')
 const resetPath = config.get('invite-reset-password.url')
 const resetPasswordPath = config.get('invite-reviewer.url')
 const forgotPath = config.get('forgot-password.url')
+const unsubscribeSlug = config.get('unsubscribe.url')
 
 module.exports = {
   sendSimpleEmail: async ({
@@ -18,6 +19,13 @@ module.exports = {
     let subject, textBody
     let emailTemplate = 'simpleCTA'
     const replacements = {}
+    replacements.unsubscribeLink = helpers.createUrl(
+      dashboardUrl,
+      unsubscribeSlug,
+      {
+        id: user.id,
+      },
+    )
     switch (emailType) {
       case 'assign-handling-editor':
         subject = 'Hindawi Handling Editor Invitation'
@@ -28,6 +36,7 @@ module.exports = {
         replacements.previewText = 'An Editor in Chief has assigned you'
         replacements.buttonText = 'VIEW DASHBOARD'
         replacements.url = dashboardUrl
+
         textBody = `${replacements.headline} ${replacements.paragraph} ${
           replacements.url
         } ${replacements.buttonText}`
@@ -236,6 +245,9 @@ module.exports = {
       previewText: 'invitation from Hindawi',
       intro: `Dear ${user.firstName} ${user.lastName}`,
       manuscriptText: '',
+      unsubscribeLink: helpers.createUrl(baseUrl, unsubscribeSlug, {
+        id: user.id,
+      }),
     }
     let textBody
     switch (emailType) {
@@ -306,8 +318,8 @@ module.exports = {
     return Email.send(mailData)
   },
   sendNotificationEmail: async ({
-    toEmail,
     user,
+    toEmail,
     emailType,
     meta = { privateNote: '' },
   }) => {
@@ -324,9 +336,12 @@ module.exports = {
       : ''
     const replacements = {
       detailsUrl,
-      beforeAnchor: '',
-      afterAnchor: '',
       hasLink: true,
+      afterAnchor: '',
+      beforeAnchor: '',
+      unsubscribeLink: helpers.createUrl(meta.baseUrl, unsubscribeSlug, {
+        id: user.id,
+      }),
     }
     switch (emailType) {
       case 'unassign-reviewer':
diff --git a/packages/component-mail-service/src/helpers/helpers.js b/packages/component-mail-service/src/helpers/helpers.js
index 6f6a01f113ca5124039f23e26d3d49316163f0b2..12b4dafaebc92d85c55059e28d5974969f2dff3b 100644
--- a/packages/component-mail-service/src/helpers/helpers.js
+++ b/packages/component-mail-service/src/helpers/helpers.js
@@ -9,7 +9,7 @@ const createUrl = (baseUrl, slug, queryParams = null) =>
 
 const getEmailBody = (emailType, replacements) => {
   handlePartial('header', replacements)
-  handlePartial('footer')
+  handlePartial('footer', replacements)
   handlePartial('mainButton', replacements)
   handlePartial('mainBody', replacements)
 
@@ -18,7 +18,7 @@ const getEmailBody = (emailType, replacements) => {
 
 const getNotificationBody = (emailType, replacements) => {
   handlePartial('notificationHeader', replacements)
-  handlePartial('footer')
+  handlePartial('footer', replacements)
   handlePartial('signature', replacements)
   if (replacements.detailsUrl !== undefined)
     handlePartial('manuscriptDetailsLink', replacements)
@@ -29,7 +29,7 @@ const getNotificationBody = (emailType, replacements) => {
 
 const getInvitationBody = (emailType, replacements) => {
   handlePartial('invitationHeader', replacements)
-  handlePartial('footer')
+  handlePartial('footer', replacements)
   handlePartial('invitationUpperContent', replacements)
   handlePartial('invitationButtons', replacements)
   handlePartial('manuscriptData', replacements)
@@ -117,10 +117,10 @@ const getExpectedDate = (timestamp, daysExpected) => {
 }
 
 module.exports = {
+  getBody,
   createUrl,
   getEmailBody,
   getExpectedDate,
   getNotificationBody,
   getInvitationBody,
-  getBody,
 }
diff --git a/packages/component-mail-service/src/templates/partials/footer.hbs b/packages/component-mail-service/src/templates/partials/footer.hbs
index 4b93ccf593422d3e04aa70665ac05fa03a65af0d..355088275373e0378176b00ca6a9007cc2d54a62 100644
--- a/packages/component-mail-service/src/templates/partials/footer.hbs
+++ b/packages/component-mail-service/src/templates/partials/footer.hbs
@@ -10,7 +10,7 @@
     </p>
   </div>
   <p style="font-family:Arial, Helvetica, sans-serif;font-size:12px;line-height:20px">
-    <a class="Unsubscribe--unsubscribeLink" href="[Unsubscribe]">Unsubscribe</a>
+    <a class="Unsubscribe--unsubscribeLink" href="{{ unsubscribeLink }}">Unsubscribe</a>
   </p>
 </div>
 </td>
diff --git a/packages/component-user-manager/src/Users.js b/packages/component-user-manager/src/Users.js
index 95d064990c554472413277282e82986111fc8609..38c40169905ab9f328657e7721bb0a98d65f369e 100644
--- a/packages/component-user-manager/src/Users.js
+++ b/packages/component-user-manager/src/Users.js
@@ -125,6 +125,44 @@ const Users = app => {
     require('./routes/users/changePassword')(app.locals.models),
   )
 
+  /**
+   * @api {patch} /api/users/subscriptions Change user's email subscription flag
+   * @apiGroup Users
+   * @apiParamExample {json} Body
+   *    {
+   *      "id": "a6184463-b17a-42f8-b02b-ae1d755cdc6b",
+   *      "subscribe": true,
+   *    }
+   * @apiSuccessExample {json} Success
+   *    HTTP/1.1 200 OK
+   *    {
+   *      "id": "a6184463-b17a-42f8-b02b-ae1d755cdc6b",
+   *      "type": "user",
+   *      "admin": false,
+   *      "email": "email@example.com",
+   *      "teams": [],
+   *      "username": "email@example.com",
+   *      "fragments": [],
+   *      "collections": [],
+   *      "isConfirmed": true,
+   *      "editorInChief": false,
+   *      "handlingEditor": false,
+   *      "notifications": {
+   *        "email": {
+   *           "system": true,
+   *           "user": true
+   *         }
+   *       }
+   *    }
+   * @apiErrorExample {json} Reset password errors
+   *    HTTP/1.1 400 Bad Request
+   *    HTTP/1.1 404 Not Found
+   */
+  app.patch(
+    '/api/users/subscribe',
+    require('./routes/users/subscribe')(app.locals.models),
+  )
+
   // register ORCID authentication strategy
   orcidRoutes(app)
 }
diff --git a/packages/component-user-manager/src/routes/users/subscribe.js b/packages/component-user-manager/src/routes/users/subscribe.js
new file mode 100644
index 0000000000000000000000000000000000000000..fa90c8481012b0c8e045842764c508d8b0332d48
--- /dev/null
+++ b/packages/component-user-manager/src/routes/users/subscribe.js
@@ -0,0 +1,23 @@
+const { set } = require('lodash')
+const { services } = require('pubsweet-component-helper-service')
+
+module.exports = models => async (req, res) => {
+  const { subscribe, id } = req.body
+
+  if (!services.checkForUndefinedParams(subscribe, id))
+    return res.status(400).json({ error: 'Missing required params.' })
+
+  let user
+  try {
+    user = await models.User.find(id)
+    set(user, 'notifications.email.user', subscribe)
+    user = await user.save()
+
+    return res.status(200).json({ user })
+  } catch (e) {
+    const notFoundError = await services.handleNotFoundError(e, 'User')
+    return res.status(notFoundError.status).json({
+      error: notFoundError.message,
+    })
+  }
+}
diff --git a/packages/components-faraday/src/components/Admin/AdminUsers.js b/packages/components-faraday/src/components/Admin/AdminUsers.js
index ecaf18ab7d11af51e6ef304bd2f252b78a111dc0..2fe5afe3a8274416b3895fe1bbd60f3d4c7fd6e6 100644
--- a/packages/components-faraday/src/components/Admin/AdminUsers.js
+++ b/packages/components-faraday/src/components/Admin/AdminUsers.js
@@ -142,10 +142,10 @@ export default compose(
       setPage(p => (p > 0 ? p - 1 : p))
     },
     getStatusLabel: () => ({ isConfirmed, isActive = true }) => () => {
-      if (isConfirmed) {
-        return isActive ? 'Active' : 'Inactive'
+      if (!isActive) {
+        return 'Inactive'
       }
-      return 'Invited'
+      return isConfirmed ? 'Active' : 'Invited'
     },
     toggleUserStatus: ({
       dispatch,
diff --git a/packages/components-faraday/src/components/Admin/utils.js b/packages/components-faraday/src/components/Admin/utils.js
index 99934cd10843f0d3332497abf7c6223c9b6ca63d..2cb2c8023b37cc29e41b5972151dda42cc3ffe03 100644
--- a/packages/components-faraday/src/components/Admin/utils.js
+++ b/packages/components-faraday/src/components/Admin/utils.js
@@ -31,6 +31,12 @@ export const setAdmin = values => {
     password: 'defaultpass',
     editorInChief: newValues.role === 'editorInChief',
     handlingEditor: newValues.role === 'handlingEditor',
+    notifications: {
+      email: {
+        system: true,
+        user: true,
+      },
+    },
   }
 }
 
diff --git a/packages/components-faraday/src/components/UserProfile/AccountDetails.js b/packages/components-faraday/src/components/UserProfile/AccountDetails.js
index 768c8a46ecafb78fb2b7ab543e18792365d92b03..81080db096d193b2d48cac5a881ce79fe5eee5a2 100644
--- a/packages/components-faraday/src/components/UserProfile/AccountDetails.js
+++ b/packages/components-faraday/src/components/UserProfile/AccountDetails.js
@@ -29,7 +29,7 @@ export default compose(
   withJournal,
   withState('isEdit', 'setEdit', false),
   withHandlers({
-    setEditMode: ({ setEdit }) => value => setEdit(value),
+    setEditMode: ({ setEdit }) => value => () => setEdit(value),
   }),
 )(AccountDetails)
 
diff --git a/packages/components-faraday/src/components/UserProfile/AccountDetailsCard.js b/packages/components-faraday/src/components/UserProfile/AccountDetailsCard.js
index 22dadc2aa731f7a0406cc81ff7e968b736bc709e..7e085536a808b582f8faa40dfbfc2fb5a1602e95 100644
--- a/packages/components-faraday/src/components/UserProfile/AccountDetailsCard.js
+++ b/packages/components-faraday/src/components/UserProfile/AccountDetailsCard.js
@@ -3,10 +3,10 @@ import React, { Fragment } from 'react'
 import {
   Row,
   RowItem,
-  LabelHeader,
+  LinkText,
   LabelTitle,
+  LabelHeader,
   DefaultText,
-  LinkText,
 } from '../UIComponents/FormItems'
 import { getUserTitle } from '../utils'
 
@@ -48,7 +48,7 @@ const AccountDetailsCard = ({
     </Row>
     <Row noMargin>
       <RowItem>
-        <LinkText onClick={() => setEditMode(true)}>Edit details</LinkText>
+        <LinkText onClick={setEditMode(true)}>Edit details</LinkText>
         <LinkText onClick={() => history.push('/profile/change-password')}>
           Change Password
         </LinkText>
diff --git a/packages/components-faraday/src/components/UserProfile/AccountDetailsEdit.js b/packages/components-faraday/src/components/UserProfile/AccountDetailsEdit.js
index f247552c6e71b68f61cbda82f37ee768f8fb20ee..a88c42c6e5d004d6642e21faa60c45940dde1505 100644
--- a/packages/components-faraday/src/components/UserProfile/AccountDetailsEdit.js
+++ b/packages/components-faraday/src/components/UserProfile/AccountDetailsEdit.js
@@ -11,7 +11,7 @@ const AccountDetailsEdit = ({ journal, user, setEditMode, handleSubmit }) => (
   <Root onSubmit={handleSubmit}>
     <EditUserForm journal={journal} title="Edit account details" user={user} />
     <Row>
-      <Button onClick={() => setEditMode(false)}>Cancel</Button>
+      <Button onClick={setEditMode(false)}>Cancel</Button>
       <Button primary type="submit">
         Save
       </Button>
diff --git a/packages/components-faraday/src/components/UserProfile/EmailNotifications.js b/packages/components-faraday/src/components/UserProfile/EmailNotifications.js
index 853c24047d9ff22f56f13d0ffa96eb1ff9044961..025b39f98420336584e02dbbd0e5865204302840 100644
--- a/packages/components-faraday/src/components/UserProfile/EmailNotifications.js
+++ b/packages/components-faraday/src/components/UserProfile/EmailNotifications.js
@@ -1,9 +1,14 @@
 import React from 'react'
 import styled from 'styled-components'
+import { compose, withHandlers } from 'recompose'
+import {
+  withModal,
+  ConfirmationModal,
+} from 'pubsweet-component-modal/src/components'
 
 import { Row, RowItem, LabelHeader, LinkText } from '../UIComponents/FormItems'
 
-const EmailNotifications = ({ subscribed = '' }) => (
+const EmailNotifications = ({ subscribed = '', subscribe, unsubscribe }) => (
   <Root>
     <Row noMargin>
       <RowItem>
@@ -13,20 +18,58 @@ const EmailNotifications = ({ subscribed = '' }) => (
     {!subscribed ? (
       <Row noMargin>
         <RowItem>
-          <LinkText>Re-subscribe</LinkText>
+          <LinkText onClick={subscribe}>Re-subscribe</LinkText>
         </RowItem>
       </Row>
     ) : (
       <Row noMargin>
         <RowItem>
-          <LinkText>Unsubscribe</LinkText>
+          <LinkText onClick={unsubscribe}>Unsubscribe</LinkText>
         </RowItem>
       </Row>
     )}
   </Root>
 )
 
-export default EmailNotifications
+export default compose(
+  withModal(props => ({
+    modalComponent: ConfirmationModal,
+  })),
+  withHandlers({
+    subscribe: ({
+      userId,
+      showModal,
+      hideModal,
+      changeEmailSubscription,
+    }) => () => {
+      showModal({
+        title: 'Subscribe to emails',
+        subtitle: 'Are you sure you want to subscribe to emails?',
+        onConfirm: () => {
+          changeEmailSubscription(userId, false)
+          hideModal()
+        },
+        onCancel: hideModal,
+      })
+    },
+    unsubscribe: ({
+      userId,
+      showModal,
+      hideModal,
+      changeEmailSubscription,
+    }) => () => {
+      showModal({
+        title: 'Unsubscribe from emails',
+        subtitle: 'Are you sure you want to unsubscribe from emails?',
+        onConfirm: () => {
+          changeEmailSubscription(userId, true)
+          hideModal()
+        },
+        onCancel: hideModal,
+      })
+    },
+  }),
+)(EmailNotifications)
 
 // #region styles
 const Root = styled.div`
diff --git a/packages/components-faraday/src/components/UserProfile/Unsubscribe.js b/packages/components-faraday/src/components/UserProfile/Unsubscribe.js
new file mode 100644
index 0000000000000000000000000000000000000000..9e1232cdb0ecab224cfd4965a3c4a7718bb7c17c
--- /dev/null
+++ b/packages/components-faraday/src/components/UserProfile/Unsubscribe.js
@@ -0,0 +1,63 @@
+import React from 'react'
+import { connect } from 'react-redux'
+import { Button } from '@pubsweet/ui'
+import styled from 'styled-components'
+import { th } from '@pubsweet/ui-toolkit'
+import { compose, lifecycle, withState } from 'recompose'
+
+import { parseSearchParams } from '../utils'
+import { changeEmailSubscription } from '../../redux/users'
+
+const Unsubscribe = ({ message, history }) => (
+  <Root>
+    <Title>{message}</Title>
+    <Button onClick={() => history.replace('/')} primary>
+      Go to Dashboard
+    </Button>
+  </Root>
+)
+
+const confirmMessage = `You have successfully unsubscribed from emails. To resubscribe go the your profile.`
+const errorMessage = `Something went wrong with your account confirmation. Please try again.`
+
+export default compose(
+  connect(null, { changeEmailSubscription }),
+  withState('message', 'setConfirmMessage', 'Loading...'),
+  lifecycle({
+    componentDidMount() {
+      const {
+        location,
+        setConfirmMessage,
+        changeEmailSubscription,
+      } = this.props
+      const { id } = parseSearchParams(location.search)
+      changeEmailSubscription(id, false)
+        .then(() => {
+          setConfirmMessage(confirmMessage)
+        })
+        .catch(() => {
+          setConfirmMessage(errorMessage)
+        })
+    },
+  }),
+)(Unsubscribe)
+
+// #region styled components
+const Root = styled.div`
+  color: ${th('colorText')};
+  margin: 0 auto;
+  text-align: center;
+  width: 70vw;
+
+  a {
+    color: ${th('colorText')};
+  }
+`
+
+const Title = styled.div`
+  color: ${th('colorPrimary')};
+  font-size: ${th('fontSizeHeading5')};
+  font-family: ${th('fontHeading')};
+  margin: 10px auto;
+`
+// #endregion
diff --git a/packages/components-faraday/src/components/UserProfile/UserProfilePage.js b/packages/components-faraday/src/components/UserProfile/UserProfilePage.js
index 462abc4c48ed0be8bc05cbab2e7a147cc640b537..7e4e7cbd7ca651475ac08983c561ff580f27607c 100644
--- a/packages/components-faraday/src/components/UserProfile/UserProfilePage.js
+++ b/packages/components-faraday/src/components/UserProfile/UserProfilePage.js
@@ -6,11 +6,12 @@ import styled from 'styled-components'
 import { selectCurrentUser } from 'xpub-selectors'
 import { BreadcrumbsHeader } from 'pubsweet-components-faraday/src/components'
 
-import AccountDetails from './AccountDetails'
 import LinkOrcID from './LinkOrcID'
+import AccountDetails from './AccountDetails'
 import EmailNotifications from './EmailNotifications'
+import { changeEmailSubscription } from '../../redux/users'
 
-const UserProfilePage = ({ history, user }) => (
+const UserProfilePage = ({ history, user, changeEmailSubscription }) => (
   <Root>
     <BreadcrumbsHeader
       history={history}
@@ -20,15 +21,22 @@ const UserProfilePage = ({ history, user }) => (
       underlined
     />
     <AccountDetails history={history} user={user} />
-    <EmailNotifications subscribed={get(user, 'subscription')} />
+    <EmailNotifications
+      changeEmailSubscription={changeEmailSubscription}
+      subscribed={get(user, 'notifications.email.user')}
+      userId={get(user, 'id')}
+    />
     <LinkOrcID id={get(user, 'id')} orcid={get(user, 'orcid')} />
   </Root>
 )
 
 export default compose(
-  connect(state => ({
-    user: selectCurrentUser(state),
-  })),
+  connect(
+    state => ({
+      user: selectCurrentUser(state),
+    }),
+    { changeEmailSubscription },
+  ),
 )(UserProfilePage)
 
 // #region styles
diff --git a/packages/components-faraday/src/components/UserProfile/index.js b/packages/components-faraday/src/components/UserProfile/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..9d8f501405da336f0374b73693d3183c961399c0
--- /dev/null
+++ b/packages/components-faraday/src/components/UserProfile/index.js
@@ -0,0 +1 @@
+export { default as Unsubscribe } from './Unsubscribe'
diff --git a/packages/components-faraday/src/redux/users.js b/packages/components-faraday/src/redux/users.js
index a4e6d1a12984cde20989701eadbeddae1728779b..460f254083804ddddadef2baf826d461cd88f0d5 100644
--- a/packages/components-faraday/src/redux/users.js
+++ b/packages/components-faraday/src/redux/users.js
@@ -1,5 +1,6 @@
 import { get } from 'lodash'
-import { create } from 'pubsweet-client/src/helpers/api'
+import { actions } from 'pubsweet-client'
+import { create, update } from 'pubsweet-client/src/helpers/api'
 
 const LOGIN_SUCCESS = 'LOGIN_SUCCESS'
 
@@ -20,3 +21,9 @@ export const confirmUser = (userId, confirmationToken) => dispatch =>
     localStorage.setItem('token', user.token)
     return dispatch(loginSuccess(user))
   })
+
+export const changeEmailSubscription = (id, subscribe = true) => dispatch =>
+  update(`/users/subscribe`, {
+    id,
+    subscribe,
+  }).then(() => dispatch(actions.getCurrentUser()))
diff --git a/packages/xpub-faraday/app/routes.js b/packages/xpub-faraday/app/routes.js
index 826ed981b7f01bdab32619dac5de12f1d87e7124..e06874ce684fa21817fa7e679c940b824f5abc92 100644
--- a/packages/xpub-faraday/app/routes.js
+++ b/packages/xpub-faraday/app/routes.js
@@ -29,6 +29,8 @@ import {
   SignUpInvitationPage,
 } from 'pubsweet-components-faraday/src/components/SignUp'
 
+import { Unsubscribe } from 'pubsweet-components-faraday/src/components/UserProfile'
+
 import FaradayApp from './FaradayApp'
 
 const PrivateRoute = ({ component: Component, ...rest }) => (
@@ -84,6 +86,7 @@ const Routes = () => (
         path="/forgot-password"
       />
       <Route component={ConfirmAccount} exact path="/confirm-signup" />
+      <Route component={Unsubscribe} exact path="/unsubscribe" />
       <PrivateRoute component={DashboardPage} exact path="/" />
       <PrivateRoute component={UserProfilePage} exact path="/profile" />
       <PrivateRoute
diff --git a/packages/xpub-faraday/config/default.js b/packages/xpub-faraday/config/default.js
index 37367502a5d21c4d8aeb99f715a44c9e8ec16614..22d48a7d70e81b486f47841d157e79f137882789 100644
--- a/packages/xpub-faraday/config/default.js
+++ b/packages/xpub-faraday/config/default.js
@@ -83,6 +83,9 @@ module.exports = {
   'confirm-signup': {
     url: process.env.PUBSWEET_CONFIRM_SIGNUP_URL || '/confirm-signup',
   },
+  unsubscribe: {
+    url: process.env.PUBSWEET_UNSUBSCRIBE_URL || '/unsubscribe',
+  },
   roles: {
     global: ['admin', 'editorInChief', 'author', 'handlingEditor'],
     collection: ['handlingEditor', 'reviewer', 'author'],
diff --git a/packages/xpub-faraday/config/validations.js b/packages/xpub-faraday/config/validations.js
index 61e603fe92ae1d12ffedecae79d2774207df71ed..c9e88be1e2e28bd24489ebb4e49d45f146184f86 100644
--- a/packages/xpub-faraday/config/validations.js
+++ b/packages/xpub-faraday/config/validations.js
@@ -131,6 +131,12 @@ module.exports = {
     confirmationToken: Joi.string().allow(''),
     agreeTC: Joi.boolean(),
     isActive: Joi.boolean().default(true),
+    notifications: Joi.object({
+      email: Joi.object({
+        system: Joi.boolean().default(true),
+        user: Joi.boolean().default(true),
+      }),
+    }),
   },
   team: {
     group: Joi.string(),