diff --git a/resources/static/dialog/start.js b/resources/static/dialog/start.js
index 5312cfbb826c94161d8d24fe9374b57655f8662a..1d0655877c632dfd28b18d2fe025877c464dca4f 100644
--- a/resources/static/dialog/start.js
+++ b/resources/static/dialog/start.js
@@ -14,8 +14,11 @@
   xhr.init({ time_until_delay: 10 * 1000 });
   network.init();
 
+  var hash = window.location.hash || "",
+      continuation = hash.indexOf("#CREATE_EMAIL") > -1 || hash.indexOf("#ADD_EMAIL") > -1;
+
   moduleManager.register("interaction_data", modules.InteractionData);
-  moduleManager.start("interaction_data");
+  moduleManager.start("interaction_data", { continuation: continuation });
 
   moduleManager.register("cookie_check", modules.CookieCheck);
   moduleManager.start("cookie_check", {
diff --git a/resources/static/shared/modules/interaction_data.js b/resources/static/shared/modules/interaction_data.js
index b08ef54163ce99f2f8760790a89da287e71e44f6..458478ed645672d646fc768a615114a80735b4dd 100644
--- a/resources/static/shared/modules/interaction_data.js
+++ b/resources/static/shared/modules/interaction_data.js
@@ -21,7 +21,6 @@
 // TODO:
 //  * should code explicitly call .addEvent?  or instead should this module
 //    listen for events via the mediator?
-//  * the primary flow will cause unload and reload.  omg.  How do we deal?
 
 BrowserID.Modules.InteractionData = (function() {
   var bid = BrowserID,
@@ -38,10 +37,10 @@ BrowserID.Modules.InteractionData = (function() {
     if (self.sessionContextHandled) return;
     self.sessionContextHandled = true;
 
-    // Publish any outstanding data.  Previous session data must be published
-    // independently of whether the current dialog session is allowed to sample
-    // data. This is because the original dialog session has already decided
-    // whether to collect data.
+    // Publish any outstanding data.  Unless this is a continuation, previous
+    // session data must be published independently of whether the current
+    // dialog session is allowed to sample data. This is because the original
+    // dialog session has already decided whether to collect data.
     publishStored();
 
     // set the sample rate as defined by the server.  It's a value
@@ -49,7 +48,7 @@ BrowserID.Modules.InteractionData = (function() {
     // of the time that we should capture
     var sampleRate = result.data_sample_rate || 0;
 
-    if(typeof self.samplingEnabled === "undefined") {
+    if (typeof self.samplingEnabled === "undefined") {
       // now that we've got sample rate, let's smash it into a boolean
       // probalistically
       self.samplingEnabled = Math.random() <= sampleRate;
@@ -64,6 +63,7 @@ BrowserID.Modules.InteractionData = (function() {
       event_stream: self.initialEventStream,
       sample_rate: sampleRate,
       timestamp: result.server_time,
+      local_timestamp: self.startTime.toString(),
       lang: dom.getAttr('html', 'lang') || null,
     };
 
@@ -130,26 +130,53 @@ BrowserID.Modules.InteractionData = (function() {
 
       var self = this;
 
-      self.startTime = new Date();
-
-      // If samplingEnabled is not specified in the options, it will be decided
-      // on the first "context_info" event, which corresponds to the first time
-      // we get 'session_context' from the server.
-      //
       // options.samplingEnabled is used for testing purposes.
+      //
+      // If samplingEnabled is not specified in the options, and this is not
+      // a continuation, samplingEnabled will be decided on the first "
+      // context_info" event, which corresponds to the first time
+      // 'session_context' returns from the server.
       self.samplingEnabled = options.samplingEnabled;
 
-      // The initialEventStream is used to store events until onSessionContext
-      // is called.  Once onSessionContext is called and it is known whether
-      // the user's data will be saved, initialEventStream will either be
-      // discarded or added to the data set that is saved to localStorage.
-      self.initialEventStream = [];
-      self.samplesBeingStored = false;
-
-      // whenever session_context is hit, let's hear about it so we can
-      // extract the information that's important to us (like, whether we
-      // should be running or not)
-      this.subscribe('context_info', onSessionContext);
+      // continuation means the users dialog session is continuing, probably
+      // due to a redirect to an IdP and then a return after authentication.
+      if (options.continuation) {
+        var previousData = storage.current();
+
+        var samplingEnabled = self.samplingEnabled = !!previousData.event_stream;
+        if (samplingEnabled) {
+          self.startTime = Date.parse(previousData.local_timestamp);
+
+          if (typeof self.samplingEnabled === "undefined") {
+            self.samplingEnabled = samplingEnabled;
+          }
+
+          // instead of waiting for session_context to start appending data to
+          // localStorage, start saving into localStorage now.
+          self.samplesBeingStored = true;
+        }
+        else {
+          // If there was no previous event stream, that means data collection
+          // was not allowed for the previous session.  Return with no further
+          // action, data collection is not allowed for this session either.
+          return;
+        }
+      }
+      else {
+        self.startTime = new Date();
+
+        // The initialEventStream is used to store events until onSessionContext
+        // is called.  Once onSessionContext is called and it is known whether
+        // the user's data will be saved, initialEventStream will either be
+        // discarded or added to the data set that is saved to localStorage.
+        self.initialEventStream = [];
+        self.samplesBeingStored = false;
+
+        // whenever session_context is hit, let's hear about it so we can
+        // extract the information that's important to us (like, whether we
+        // should be running or not)
+        self.contextInfoHandle = this.subscribe('context_info', onSessionContext);
+      }
 
       // on all events, update event_stream
       this.subscribeAll(addEvent);
@@ -163,7 +190,7 @@ BrowserID.Modules.InteractionData = (function() {
     },
 
     getEventStream: function() {
-      return this.samplesBeingStored ? storage.current().event_stream : this.initialEventStream;
+      return this.samplesBeingStored ? storage.current().event_stream : this.initialEventStream || [];
     },
 
     publishStored: publishStored
diff --git a/resources/static/test/cases/shared/modules/interaction_data.js b/resources/static/test/cases/shared/modules/interaction_data.js
index 818ca815363b33e2395e38b88e007aa24fcd0a8d..951c506903538a898a6e0c80c8fa8913aeff3593 100644
--- a/resources/static/test/cases/shared/modules/interaction_data.js
+++ b/resources/static/test/cases/shared/modules/interaction_data.js
@@ -111,10 +111,76 @@
 
       equal(typeof controller.getCurrentStoredData(), "undefined", "no stored data");
 
+      controller.publishStored(function(status) {
+        equal(status, false, "there was no data to publish");
+        start();
+      });
+    });
+  });
+
+  asyncTest("continue: true, data collection permitted on previous session - continue appending data to previous session", function() {
+    createController();
+
+    controller.addEvent("session1_before_session_context");
+    network.withContext(function() {
+      controller.addEvent("session1_after_session_context");
+
+      // simulate a restart of the dialog.  Clear the session_context and then
+      // re-get session context.
+      controller = null;
+      network.clearContext();
+      createController({ continuation: true });
+
+      controller.addEvent("session2_before_session_context");
+      network.withContext(function() {
+        controller.addEvent("session2_after_session_context");
+
+        var events = controller.getEventStream();
+
+        ok(indexOfEvent(events, "session1_before_session_context") > -1, "session1_before_session_context correctly saved to current event stream");
+        ok(indexOfEvent(events, "session1_after_session_context") > -1, "session1_after_session_context correctly saved to current event stream");
+        ok(indexOfEvent(events, "session2_before_session_context") > -1, "session2_before_session_context correctly saved to current event stream");
+        ok(indexOfEvent(events, "session2_after_session_context") > -1, "session2_after_session_context correctly saved to current event stream");
+
+      });
+
       start();
     });
 
   });
 
+  asyncTest("continue: true, data collection not permitted in previous session - no data collected", function() {
+    createController({ samplingEnabled: false });
+
+    controller.addEvent("session1_before_session_context");
+    network.withContext(function() {
+      controller.addEvent("session1_after_session_context");
+
+      // simulate a restart of the dialog.  Clear the session_context and then
+      // re-get session context.
+      controller = null;
+      network.clearContext();
+      createController({ continuation: true });
+
+      controller.addEvent("session2_before_session_context");
+      network.withContext(function() {
+        controller.addEvent("session2_after_session_context");
+
+        var events = controller.getEventStream();
+
+        ok(indexOfEvent(events, "session1_before_session_context") === -1, "no data collected");
+        ok(indexOfEvent(events, "session1_after_session_context") === -1, "no data collected");
+        ok(indexOfEvent(events, "session2_before_session_context") === -1, "no data collected");
+        ok(indexOfEvent(events, "session2_after_session_context") === -1, "no data collected");
+
+        controller.publishStored(function(status) {
+          equal(status, false, "there was no data to publish");
+          start();
+        });
+      });
+    });
+
+  });
+
 
 }());