diff --git a/app/styles/account/unsubscribe.sass b/app/styles/account/unsubscribe.sass
new file mode 100644
index 000000000..ad75f5e30
--- /dev/null
+++ b/app/styles/account/unsubscribe.sass
@@ -0,0 +1,8 @@
+#unsubscribe-view
+  text-align: center
+  
+  p
+    margin: 20px 0
+  
+  .bar
+    width: 100%
\ No newline at end of file
diff --git a/app/templates/account/unsubscribe.jade b/app/templates/account/unsubscribe.jade
new file mode 100644
index 000000000..973df4eac
--- /dev/null
+++ b/app/templates/account/unsubscribe.jade
@@ -0,0 +1,17 @@
+extends /templates/base
+
+block content
+  
+  p
+    span(data-i18n="account.unsubscribe") Unsubscribing for
+    span  
+    strong= email
+  
+  button.btn.btn-warning#unsubscribe-button(data-i18n="account.unsubscribe_button") Do it
+
+  .progress.progress-striped.active.hide
+    .bar
+      
+  p.hide#fail-alert(data-i18n="account.unsubscribe_failed").alert.alert-danger Failed
+    
+  p.hide#success-alert(data-i18n="account.unsubscribe_success").alert.alert-success Success
diff --git a/app/views/account/unsubscribe_view.coffee b/app/views/account/unsubscribe_view.coffee
new file mode 100644
index 000000000..f9320e216
--- /dev/null
+++ b/app/views/account/unsubscribe_view.coffee
@@ -0,0 +1,35 @@
+RootView = require 'views/kinds/RootView'
+template = require 'templates/account/unsubscribe'
+{me} = require 'lib/auth'
+
+module.exports = class UnsubscribeView extends RootView
+  id: "unsubscribe-view"
+  template: template
+  
+  events:
+    'click #unsubscribe-button': 'onUnsubscribeButtonClicked'
+
+  getRenderData: ->
+    context = super()
+    context.email = @getQueryVariable 'email'
+    context
+
+  onUnsubscribeButtonClicked: ->
+    @$el.find('#unsubscribe-button').addClass 'hide'
+    @$el.find('.progress').removeClass 'hide'
+    @$el.find('.alert').addClass 'hide'
+    
+    email = @getQueryVariable 'email'
+    url = "/auth/unsubscribe?email=#{encodeURIComponent(email)}"
+    
+    success = =>
+      @$el.find('.progress').addClass 'hide'
+      @$el.find('#success-alert').removeClass 'hide'
+      me.fetch()
+      
+    error = =>
+      @$el.find('.progress').addClass 'hide'
+      @$el.find('#fail-alert').removeClass 'hide'
+      @$el.find('#unsubscribe-button').removeClass 'hide'
+      
+    $.ajax { url: url, success: success, error: error }
diff --git a/server/auth.coffee b/server/auth.coffee
index 83d850894..8c15becba 100644
--- a/server/auth.coffee
+++ b/server/auth.coffee
@@ -79,6 +79,22 @@ module.exports.setupRoutes = (app) ->
           return res.end()
     )
   )
+  
+  app.get '/auth/unsubscribe', (req, res) ->
+    email = req.query.email
+    unless req.query.email
+      return errors.badInput res, 'No email provided to unsubscribe.'
+      
+    User.findOne({emailLower:req.query.email.toLowerCase()}).exec (err, user) ->
+      if not user
+        return errors.notFound res, "No user found with email '#{req.query.email}'"
+
+      user.set('emailSubscriptions', [])
+      user.save (err) =>
+        return errors.serverError res, 'Database failure.' if err
+
+        res.send "Unsubscribed #{req.query.email} from all CodeCombat emails. Sorry to see you go! <p><a href='/account/settings'>Account settings</a></p>"
+        res.end()
 
 createMailOptions = (receiver, password) ->
   # TODO: use email templates here