diff --git a/examples/room_feed.cpp b/examples/room_feed.cpp
index a76c4d65e69aa0fe56d11dc577d7e548ab85bad0..3a1679935342eb1483c3de90c2e3196dae4c08c5 100644
--- a/examples/room_feed.cpp
+++ b/examples/room_feed.cpp
@@ -19,6 +19,17 @@ using namespace mtx::events;
 using ErrType       = experimental::optional<mtx::client::errors::ClientError>;
 using TimelineEvent = mtx::events::collections::TimelineEvents;
 
+void
+print_errors(ErrType err)
+{
+        if (err->status_code != boost::beast::http::status::unknown)
+                cout << err->status_code << "\n";
+        if (!err->matrix_error.error.empty())
+                cout << err->matrix_error.error << "\n";
+        if (err->error_code)
+                cout << err->error_code.message() << "\n";
+}
+
 // Check if the given event has a textual representation.
 bool
 is_room_message(const TimelineEvent &event)
@@ -75,9 +86,15 @@ sync_handler(shared_ptr<Client> client, const mtx::responses::Sync &res, ErrType
 {
         if (err) {
                 cout << "sync error:\n";
-                cout << err->status_code << "\n";
-                cout << err->matrix_error.error << "\n";
-                cout << err->error_code << "\n";
+                print_errors(err);
+
+                client->sync(
+                  "",
+                  client->next_batch_token(),
+                  false,
+                  30000,
+                  std::bind(&sync_handler, client, std::placeholders::_1, std::placeholders::_2));
+
                 return;
         }
 
@@ -86,9 +103,11 @@ sync_handler(shared_ptr<Client> client, const mtx::responses::Sync &res, ErrType
                         print_message(msg);
         }
 
+        client->set_next_batch_token(res.next_batch);
+
         client->sync(
           "",
-          res.next_batch,
+          client->next_batch_token(),
           false,
           30000,
           std::bind(&sync_handler, client, std::placeholders::_1, std::placeholders::_2));
@@ -100,14 +119,9 @@ initial_sync_handler(shared_ptr<Client> client, const mtx::responses::Sync &res,
 {
         if (err) {
                 cout << "error during initial sync:\n";
-                if (err->status_code != boost::beast::http::status::unknown)
-                        cout << err->status_code << "\n";
-                if (!err->matrix_error.error.empty())
-                        cout << err->matrix_error.error << "\n";
-                if (err->error_code)
-                        cout << err->error_code.message() << "\n";
-
-                if (err->status_code == boost::beast::http::status::gateway_timeout) {
+                print_errors(err);
+
+                if (err->status_code != boost::beast::http::status::ok) {
                         cout << "retrying initial sync ...\n";
                         client->sync("",
                                      "",
@@ -122,9 +136,11 @@ initial_sync_handler(shared_ptr<Client> client, const mtx::responses::Sync &res,
                 return;
         }
 
+        client->set_next_batch_token(res.next_batch);
+
         client->sync(
           "",
-          res.next_batch,
+          client->next_batch_token(),
           false,
           30000,
           std::bind(&sync_handler, client, std::placeholders::_1, std::placeholders::_2));
diff --git a/src/client.hpp b/src/client.hpp
index 2b9c92c448a85175195a1dd5db1f1aa6cff9d7e2..97e13ab3e0feaae1e3134bbd5541f5dd4d9f6f63 100644
--- a/src/client.hpp
+++ b/src/client.hpp
@@ -36,6 +36,10 @@ public:
         int active_sessions() const { return active_sessions_.size(); }
         //! Add an access token.
         void set_access_token(const std::string &token) { access_token_ = token; }
+        //! Update the next batch token.
+        void set_next_batch_token(const std::string &token) { next_batch_token_ = token; }
+        //! Retrieve the current next batch token.
+        std::string next_batch_token() const { return next_batch_token_; }
 
         using RequestErr = std::experimental::optional<mtx::client::errors::ClientError>;
 
@@ -130,6 +134,8 @@ private:
         std::string server_;
         //! The access token that would be used for authentication.
         std::string access_token_;
+        //! The token that will be used as the 'since' parameter on the next sync request.
+        std::string next_batch_token_;
 };
 }
 }