diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/api/DmRestApi.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/api/DmRestApi.java
index a1b899842fdbb4ffb62f40d2bfe7b378bb1126da..f83e55f310de23de2904e77510249c6b7c646e2b 100644
--- a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/api/DmRestApi.java
+++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/api/DmRestApi.java
@@ -55,6 +55,8 @@ public class DmRestApi {
 
     private URL serviceUrl;
     private DmSession session = new DmSession();
+    private String loginUsername;
+    private String loginPassword;
 
     /**
      * Constructor.
@@ -78,6 +80,20 @@ public class DmRestApi {
         configureFromString(webServiceUrl);
     }
 
+    /**
+     * Constructor.
+     *
+     * @param webServiceUrl web service URL
+     * @param loginUsername login username
+     * @param loginPassword login password
+     * @throws ConfigurationError if web service URL is malformed or null
+     */
+    public DmRestApi(String webServiceUrl, String loginUsername, String loginPassword) throws ConfigurationError {
+        configureFromString(webServiceUrl);
+        this.loginUsername = loginUsername;
+        this.loginPassword = loginPassword;
+    }
+    
     /**
      * Configure web service URL from Java VM properties.
      *
@@ -85,7 +101,7 @@ public class DmRestApi {
      * null
      */
     public final void configureFromProperties() throws ConfigurationError {
-        String webServiceUrl = System.getProperty(DmProperty.WEB_SERVICE_URL_PROPERTY_NAME);
+        String webServiceUrl = System.getProperty(DmProperty.DS_WEB_SERVICE_URL_PROPERTY_NAME);
         configureFromString(webServiceUrl);
     }
 
@@ -112,6 +128,14 @@ public class DmRestApi {
         }
     }
 
+    public void setLoginUsername(String loginUsername) {
+        this.loginUsername = loginUsername;
+    }
+
+    public void setLoginPassword(String loginPassword) {
+        this.loginPassword = loginPassword;
+    }
+    
     public URL getServiceUrl() {
         return serviceUrl;
     }
@@ -463,6 +487,25 @@ public class DmRestApi {
         login(username, password, DefaultSessionId);
     }
 
+    /**
+     * Invoke GET request with login.
+     *
+     * @param requestUrl relative request path, e.g. /object
+     * @return service response string
+     * @throws DmException in case of any errors
+     */
+    public String loginAndInvokeSessionGetRequest(String requestUrl) throws DmException {
+        try {
+            // If we have session, simply invoke request.
+            session.verifyCookie();
+            return invokeSessionGetRequest(requestUrl);
+        } catch (InvalidSession ex) {
+            // Session was invalidated, login and try again
+        }
+        login(loginUsername, loginPassword);
+        return invokeSessionGetRequest(requestUrl);
+    }
+     
     /**
      * Invoke GET request.
      *
@@ -536,6 +579,26 @@ public class DmRestApi {
         }
     }
 
+    /**
+     * Invoke POST request with login.
+     *
+     * @param requestUrl relative request path, e.g. /object
+     * @param data request data
+     * @return service response string
+     * @throws DmException in case of any errors
+     */
+    public String loginAndInvokeSessionPostRequest(String requestUrl, Map<String, String> data) throws DmException {
+        try {
+            // If we have session, simply invoke request.
+            session.verifyCookie();
+            return invokeSessionPostRequest(requestUrl, data);
+        } catch (InvalidSession ex) {
+            // Session was invalidated, login and try again
+        }
+        login(loginUsername, loginPassword);
+        return invokeSessionPostRequest(requestUrl, data);
+    }
+    
     /**
      * Invoke POST request.
      *
@@ -576,6 +639,26 @@ public class DmRestApi {
         }
     }
 
+    /**
+     * Invoke PUT request with login.
+     *
+     * @param requestUrl relative request path, e.g. /object
+     * @param data request data
+     * @return service response string
+     * @throws DmException in case of any errors
+     */
+    public String loginAndInvokeSessionPutRequest(String requestUrl, Map<String, String> data) throws DmException {
+        try {
+            // If we have session, simply invoke request.
+            session.verifyCookie();
+            return invokeSessionPutRequest(requestUrl, data);
+        } catch (InvalidSession ex) {
+            // Session was invalidated, login and try again
+        }
+        login(loginUsername, loginPassword);
+        return invokeSessionPutRequest(requestUrl, data);
+    }
+    
     /**
      * Invoke PUT request.
      *
@@ -616,6 +699,25 @@ public class DmRestApi {
         }
     }
 
+    /**
+     * Invoke DELETE request with login.
+     *
+     * @param requestUrl relative request path, e.g. /object
+     * @return service response string
+     * @throws DmException in case of any errors
+     */
+    public String loginAndInvokeSessionDeleteRequest(String requestUrl) throws DmException {
+        try {
+            // If we have session, simply invoke request.
+            session.verifyCookie();
+            return invokeSessionDeleteRequest(requestUrl);
+        } catch (InvalidSession ex) {
+            // Session was invalidated, login and try again
+        }
+        login(loginUsername, loginPassword);
+        return invokeSessionDeleteRequest(requestUrl);
+    }
+    
     /**
      * Invoke DELETE request.
      *
diff --git a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/api/ExperimentDsApi.java b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/api/ExperimentDsApi.java
index de80845b8a6995892e95e6390035bb327a306f11..a60d2dce1c23aee46dc550a4aa4e8f8e7c891609 100644
--- a/src/java/DmWebPortal/src/java/gov/anl/aps/dm/api/ExperimentDsApi.java
+++ b/src/java/DmWebPortal/src/java/gov/anl/aps/dm/api/ExperimentDsApi.java
@@ -40,6 +40,19 @@ public class ExperimentDsApi extends DmRestApi {
         super(webServiceUrl);
     }
 
+
+    /**
+     * Constructor.
+     *
+     * @param webServiceUrl web service URL
+     * @param loginUsername login username
+     * @param loginPassword login password
+     * @throws ConfigurationError if web service URL is malformed or null
+     */
+    public ExperimentDsApi(String webServiceUrl, String loginUsername, String loginPassword) throws ConfigurationError {
+        super(webServiceUrl, loginUsername, loginPassword);
+    }
+    
     /**
      * Update experiment (group users, etc.).
      *
@@ -54,7 +67,7 @@ public class ExperimentDsApi extends DmRestApi {
         String requestUrl = "/experiments/update";
         HashMap<String, String> requestData = new HashMap<>();
         requestData.put("name", ArgumentUtility.encode(experimentName));
-        String jsonString = invokeSessionPutRequest(requestUrl, requestData);
+        String jsonString = loginAndInvokeSessionPutRequest(requestUrl, requestData);
         Experiment experiment = (Experiment) DmObjectFactory.createDmObject(jsonString, Experiment.class);
         return experiment;
     }
@@ -66,8 +79,7 @@ public class ExperimentDsApi extends DmRestApi {
      */
     public static void main(String[] args) {
         try {
-            ExperimentDsApi client = new ExperimentDsApi("https://dmstorage.svdev.net:22236/dm");
-            client.login("dm", "dm");
+            ExperimentDsApi client = new ExperimentDsApi("https://dmstorage.svdev.net:22236/dm", "dm", "dm");
             Experiment experiment = client.updateExperiment("e1");
             System.out.println("Updated experiment: \n" + experiment);
         } catch (DmException ex) {