diff --git a/web/org.openbravo.mobile.core/source/data/ob-requestrouter.js b/web/org.openbravo.mobile.core/source/data/ob-requestrouter.js
--- a/web/org.openbravo.mobile.core/source/data/ob-requestrouter.js
+++ b/web/org.openbravo.mobile.core/source/data/ob-requestrouter.js
@@ -81,6 +81,10 @@
         return true;
       }
 
+      // always check if we need to update online status
+      // do after the if as index can be === servers.length and server is then undefined
+      server.checkFireOnlineNotification();
+
       if (online === Boolean(server.get('online')) && (server.get('allServices') || _.filter(server.get('services'), function (srvc) {
         return srvc === service.get('name');
       }).length > 0)) {
@@ -109,10 +113,8 @@
             server.set('online', true);
             me.handle401(server);
           } else {
-            var connected = OB.MobileApp.model.get('connectedToERP');
-
-            // offline (so no retries or try offline server) or tried all servers also in !online, call the origfail
-            if (!connected || (!online && OB.RR.RequestRouter.servers.length === (index + 1))) {
+            // tried last not online server and still failing, call origFail
+            if (!online && OB.RR.RequestRouter.servers.length === (index + 1)) {
               // we tried all offline servers, no other option left, fail
               if (!ajaxRequest.done) {
                 // the done flag keeps track that the request was done.
@@ -124,10 +126,9 @@
               }
             } else if (ajaxRequest.noRetries || ajaxRequest.numberOfRetries >= OB.UTIL.localStorage.getItem('maxNumOfRequestRetries')) {
               // no retries needed, or
-              // did all the retries, change to offline for server, move to next server
-              // work with a copy of the ajaxrequest, otherwise the set to zero has strange
-              // consequences
+              // did all the retries, change to offline for the current server, move to next server
               server.changeOnlineStatus(false, ajaxRequest.ignoreForConnectionStatus);
+              ajaxRequest.numberOfRetries = 0;
               me.callServer(online, index + 1, service, ajaxRequest);
             } else {
               // do a retry
@@ -151,7 +152,9 @@
               }
               if (!ajaxRequest.done) {
                 ajaxRequest.done = true;
-                ajaxRequest.origSuccess(inSender, inResponse);
+                if (ajaxRequest.origSuccess) {
+                  ajaxRequest.origSuccess(inSender, inResponse);
+                }
               }
               // server is back
               server.changeOnlineStatus(true, ajaxRequest.ignoreForConnectionStatus);
@@ -183,6 +186,7 @@
         me.callServer(online, index + 1, service, ajaxRequest);
       }
     },
+
     handle401: function (server) {
       if (_.find(OB.RR.RequestRouter.servers.models, function (server) {
         return server.get('online') && (server.get('allServices') || _.find(server.get('services'), function (service) {
@@ -321,6 +325,11 @@
           message.set('status', 'failure');
           OB.Dal.save(message, function () {
             me.updateSyncIcon();
+
+            // in multi server online/offline notification is based on presence of messages to sync
+            if (OB.MobileApp.model.get('connectedToERP') && OB.RR.RequestRouter.servers.length > 1) {
+              OB.MobileApp.model.triggerOffLine();
+            }
           }, function () {
             OB.error(arguments);
           });
@@ -340,6 +349,11 @@
         } else if (msgs.length === 0 && !OB.UTIL.SynchronizationHelper.isModelsSynchronized()) {
           OB.UTIL.SynchronizationHelper.modelsSynchronized();
         }
+        // in multi server online/offline notification is based on presence of messages to sync
+        if (msgs.length === 0 && !OB.MobileApp.model.get('connectedToERP') && OB.RR.RequestRouter.servers.length > 1) {
+          OB.MobileApp.model.triggerOnLine();
+        }
+
       }, function () {
         OB.error(arguments);
       });
@@ -495,7 +509,10 @@
         }
         ajaxRequest.fail = function (inSender, inResponse) {
           server.changeOnlineStatus(false, ajaxRequest.ignoreForConnectionStatus);
-          ajaxRequest.origFail(inSender, inResponse);
+          // offline is controlled by the server of the webpos
+          if (OB.RR.RequestRouter.servers.length === 1) {
+            ajaxRequest.origFail(inSender, inResponse);
+          }
         };
 
         if (!ajaxRequest.origSuccess) {
@@ -509,7 +526,9 @@
 
           if (!ajaxRequest.done) {
             ajaxRequest.done = true;
-            ajaxRequest.origSuccess(inSender, inResponse);
+            if (ajaxRequest.origSuccess) {
+              ajaxRequest.origSuccess(inSender, inResponse);
+            }
           }
           server.changeOnlineStatus(true, ajaxRequest.ignoreForConnectionStatus);
         };
@@ -573,17 +592,33 @@
     changeOnlineStatus: function (newStatus, ignoreForConnectionStatus) {
       var oldStatus = Boolean(this.get('online'));
       this.set('online', newStatus);
-      if (newStatus) {
-        // we are back, send the remaining messages
-        if (!oldStatus) {
-          OB.RR.ServTypeTransaction.sendMessages();
-          if (!ignoreForConnectionStatus) {
-            // main server back online
-            OB.MobileApp.model.triggerOnLine();
-          }
-        }
-      } else if (oldStatus && !ignoreForConnectionStatus) {
-        // went offline from online for a main server
+      // single server controls online/offline status
+      // in case of multi-server then online/offline is controlled by
+      // if there are messages to be synced.
+      if (newStatus && !oldStatus) {
+        OB.RR.ServTypeTransaction.sendMessages();
+      }
+      if (!ignoreForConnectionStatus) {
+        this.checkFireOnlineNotification();
+      }
+    },
+
+    checkFireOnlineNotification: function () {
+      var connected = OB.MobileApp.model.get('connectedToERP');
+      // only use this approach for single server cases
+      // in multi-server the online/offline concept is
+      // based on the check if there are messages to sync
+      // if there are messages to sync then it is offline
+      if (OB.RR.RequestRouter.servers.length > 1) {
+        return;
+      }
+
+      if (!this.get('isCurrentServer')) {
+        return;
+      }
+      if (this.get('online') && !connected) {
+        OB.MobileApp.model.triggerOnLine();
+      } else if (!this.get('online') && connected) {
         OB.MobileApp.model.triggerOffLine();
       }
     },
@@ -623,7 +658,7 @@
     exec: function (serviceName) {
       var service, services;
 
-      OB.RR.RequestRouter.initializeProcesses();
+      OB.RR.RequestRouter.initialize();
 
       //if servers are not loaded yet, save request to send them after servers are ready
       if (OB.RR.RequestRouter.servers.length === 0) {
@@ -667,7 +702,11 @@
     pendingRequests: [],
     initialize: function () {
       var me = this,
-          tmpPendingRequests = this.pendingRequests;
+          tmpPendingRequests, foundCurrentServer = false;
+
+      OB.RR.RequestRouter.initializePreferences();
+
+      tmpPendingRequests = this.pendingRequests;
       if (this.availableServices && this.availableServices.length > 0) {
         this.pendingRequests = [];
         _.each(tmpPendingRequests, function (obj) {
@@ -683,9 +722,17 @@
 
       if (OB.UTIL.localStorage.getItem('servers')) {
         _.each(JSON.parse(OB.UTIL.localStorage.getItem('servers')), function (server) {
-          me.servers.add(new OB.RR.Server(server));
+          var newServer = new OB.RR.Server(server);
+          if (server.address.split('/')[0] === document.location.host) {
+            newServer.set('isCurrentServer', true);
+            foundCurrentServer = true;
+          } else {
+            newServer.set('isCurrentServer', false);
+          }
+          me.servers.add(newServer);
         });
       }
+
       if (OB.UTIL.localStorage.getItem('services')) {
         _.each(JSON.parse(OB.UTIL.localStorage.getItem('services')), function (service) {
           me.availableServices.add(new OB.RR.Service(service));
@@ -693,14 +740,13 @@
       }
 
       //In case current server is not in the list
-      if (!OB.UTIL.localStorage.getItem('servers') || !_.find(JSON.parse(OB.UTIL.localStorage.getItem('servers')), function (server) {
-        return server.address.split('/')[0] === document.location.host;
-      })) {
+      if (!foundCurrentServer) {
         me.servers.add(new OB.RR.Server({
           name: 'Default',
           address: null,
           online: true,
           mainServer: true,
+          isCurrentServer: true,
           allServices: true,
           services: []
         }));
@@ -719,19 +765,18 @@
       OB.RR.ServTypeTransaction.sendMessages();
     },
 
-    initializeProcesses: function () {
+    initializePreferences: function () {
       var me = this;
-      if (!OB.MobileApp.model || !OB.MobileApp.model.get('permissions')) {
+
+      if (!OB || !OB.MobileApp || !OB.MobileApp.model || !OB.MobileApp.model.get('permissions')) {
         // not yet ready, bail out
         return;
       }
 
-      OB.RR.RequestRouter.initialize();
-
-      if (this.processesInitialized) {
+      if (this.preferencesInitialized) {
         return;
       }
-      this.processesInitialized = true;
+      this.preferencesInitialized = true;
 
       function getPreference(preference, minValue, defaultValue) {
         try {
@@ -799,6 +844,26 @@
         return false;
       }
       return service.get('type') === OB.RR.ServTypeTransaction;
+    },
+
+    ignoreManifestLoadError: function () {
+      var result = false;
+
+      this.initialize();
+
+      // single server, don't ignore
+      if (!this.servers || this.servers.length <= 1) {
+        return result;
+      }
+
+      // if the current server is offline then we should ignore
+      // the manifest error
+      _.each(this.servers.models, function (srv) {
+        if (srv.get('isCurrentServer') && !srv.get('online')) {
+          result = true;
+        }
+      });
+      return result;
     }
 
   };
diff --git a/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js b/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js
--- a/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js
+++ b/web/org.openbravo.mobile.core/source/model/ob-terminal-model.js
@@ -619,15 +619,17 @@
   initActions: function (callback) {
 
     var params = {},
-        me = this;
+        me = this,
+        loginRequest, rr;
     var cacheSessionId = null;
     if (window.OB.UTIL.localStorage.getItem('cacheSessionId') && window.OB.UTIL.localStorage.getItem('cacheSessionId').length === 32) {
       cacheSessionId = window.OB.UTIL.localStorage.getItem('cacheSessionId');
     }
     params.cacheSessionId = cacheSessionId;
     params.command = 'initActions';
-    new OB.OBPOSLogin.UI.LoginRequest({
-      url: '../../org.openbravo.mobile.core.loginutils'
+    loginRequest = new OB.OBPOSLogin.UI.LoginRequest({
+      url: '../../org.openbravo.mobile.core.loginutils',
+      data: params
     }).response(this, function (inSender, inResponse) {
       if (!(window.OB.UTIL.localStorage.getItem('cacheSessionId') && window.OB.UTIL.localStorage.getItem('cacheSessionId').length === 32)) {
         window.OB.UTIL.localStorage.setItem('cacheSessionId', inResponse.cacheSessionId);
@@ -648,8 +650,11 @@
       if (callback) {
         callback();
       }
-    }).go(params);
-
+    });
+    rr = new OB.RR.Request({
+      ajaxRequest: loginRequest
+    });
+    rr.exec(loginRequest.url);
   },
 
   /**
diff --git a/web/org.openbravo.mobile.core/source/utils/ob-utilities.js b/web/org.openbravo.mobile.core/source/utils/ob-utilities.js
--- a/web/org.openbravo.mobile.core/source/utils/ob-utilities.js
+++ b/web/org.openbravo.mobile.core/source/utils/ob-utilities.js
@@ -178,7 +178,8 @@
           OB.UTIL.checkContextChange(oldContext, newContext, connectedCallback);
         }
       }, function () {
-        if (OB.MobileApp.model && OB.MobileApp.model.get('connectedToERP')) {
+        // if single server then that server controls offline/online
+        if (OB.MobileApp.model && OB.MobileApp.model.get('connectedToERP') && OB.RR.RequestRouter.servers.length === 1) {
           OB.MobileApp.model.triggerOffLine();
         }
         if (notConnectedCallback) {
