diff --git a/lib/db/json.js b/lib/db/json.js
index 9d57297a1fa76d3fdf9bc948cc14e9cde0f6af31..739cc260389414431aa41dccd441d3e228154a7e 100644
--- a/lib/db/json.js
+++ b/lib/db/json.js
@@ -367,7 +367,9 @@ exports.completePasswordReset = function(secret, cb) {
         flush();            
 
         // update the password!
-        exports.updatePassword(uid, o.passwd, cb);
+        exports.updatePassword(uid, o.passwd, function(err) {
+          cb(err, o.email, uid);
+        });
       });
     });
   });
diff --git a/lib/db/mysql.js b/lib/db/mysql.js
index dcd1cadb2a379e4c228c59f9fc3fdc47a564d8bc..18df02d44c474605e138bb52e26ab49e4807abdd 100644
--- a/lib/db/mysql.js
+++ b/lib/db/mysql.js
@@ -419,7 +419,9 @@ exports.completePasswordReset = function(secret, cb) {
           if (err) return cb(err);
       
           // update the password!
-          exports.updatePassword(uid, o.passwd, cb);
+          exports.updatePassword(uid, o.passwd, function(err) {
+            cb(err, o.email, uid);
+          });
         });
     });
   });
diff --git a/lib/wsapi/complete_reset.js b/lib/wsapi/complete_reset.js
index 32ea867c291d780220c410bc5d25e7bc00196c68..50defe478c50aede86ca85be7bf9b0b0220dbd56 100644
--- a/lib/wsapi/complete_reset.js
+++ b/lib/wsapi/complete_reset.js
@@ -78,6 +78,7 @@ exports.process = function(req, res) {
           // safe to grant them an authenticated session.
           wsapi.authenticateSession(req.session, uid, 'password',
                                     config.get('ephemeral_session_duration_ms'));
+
           res.json({ success: true });
         }
       });
diff --git a/lib/wsapi/password_reset_status.js b/lib/wsapi/password_reset_status.js
new file mode 100644
index 0000000000000000000000000000000000000000..dd1ff5767ce39583035c334dedc77dcf72fc2a8a
--- /dev/null
+++ b/lib/wsapi/password_reset_status.js
@@ -0,0 +1,53 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const
+db = require('../db.js'),
+wsapi = require('../wsapi.js'),
+logger = require('../logging.js').logger,
+httputils = require('../httputils.js'),
+sanitize = require('../sanitize.js');
+
+exports.method = 'get';
+exports.writes_db = false;
+exports.authed = false;
+exports.args = ['email'];
+exports.i18n = false;
+
+exports.process = function(req, res) {
+  var email = req.query.email;
+
+  try {
+    sanitize(email).isEmail();
+  } catch(e) {
+    var msg = "invalid arguments: " + e;
+    logger.warn("bad request received: " + msg);
+    return httputils.badRequest(res, msg);
+  }
+
+  // if the email is in the staged table, we are not complete yet.
+  // if the email is not in the staged table -
+  //   * if we are authenticated as the owner of the email we're done
+  //   * if we are not authenticated as the owner of the email, we must auth
+  db.isStaged(email, function(err, staged) {
+    if (err) wsapi.databaseDown(res, err);
+    
+    if (staged) {
+      return res.json({ status: 'pending' });
+    } else {
+      console.log("A", req.session);
+      if (wsapi.isAuthed(req, 'assertion')) {
+        console.log("B");
+        db.userOwnsEmail(req.session.userid, email, function(err, owned) {
+          console.log("C", err, owned);
+          if (err) wsapi.databaseDown(res, err);
+          else if (owned) res.json({ status: 'complete', userid: req.session.userid });
+          else res.json({ status: 'mustAuth' });
+        });
+      } else {
+        return res.json({ status: 'mustAuth' });
+      }
+    }
+  });
+};
diff --git a/tests/forgotten-pass-test.js b/tests/forgotten-pass-test.js
index a9ca24042986bb8b7a3eb33d9f79e47a07d0fd15..f10ee189708015c2c82819cd9a74bd31061ee092 100755
--- a/tests/forgotten-pass-test.js
+++ b/tests/forgotten-pass-test.js
@@ -132,9 +132,19 @@ suite.addBatch({
   }
 });
 
+suite.addBatch({
+  "reset status": {
+    topic: wsapi.get('/wsapi/password_reset_status', { email: 'first@fakeemail.com' } ),
+    "returns 'complete' before calling reset": function(err, r) {
+      assert.strictEqual(r.code, 200);
+      assert.strictEqual(JSON.parse(r.body).status, "complete");
+    }
+  }
+});
+
 // Run the "forgot_email" flow with first address. 
 suite.addBatch({
-  "re-stage first account": {
+  "reset password on first account": {
     topic: wsapi.post('/wsapi/stage_reset', {
       email: 'first@fakeemail.com',
       pass: 'secondfakepass',
@@ -181,6 +191,13 @@ suite.addBatch({
     "should work": function(err, r) {
       assert.strictEqual(JSON.parse(r.body).success, true);
     }
+  },
+  "reset status": {
+    topic: wsapi.get('/wsapi/password_reset_status', { email: 'first@fakeemail.com' } ),
+    "returns 'pending' after calling reset": function(err, r) {
+      assert.strictEqual(r.code, 200);
+      assert.strictEqual(JSON.parse(r.body).status, "pending");
+    }
   }
 });
 
@@ -197,6 +214,16 @@ suite.addBatch({
   }
 });
 
+suite.addBatch({
+  "reset status": {
+    topic: wsapi.get('/wsapi/password_reset_status', { email: 'first@fakeemail.com' } ),
+    "returns 'complete' after completing reset": function(err, r) {
+      assert.strictEqual(r.code, 200);
+      assert.strictEqual(JSON.parse(r.body).status, "complete");
+    }
+  }
+});
+
 // now we should be able to sign in using any email address
 suite.addBatch({
   "first email, first pass bad": {