diff --git a/src/main/java/net/geant/nmaas/portal/api/bulk/BulkController.java b/src/main/java/net/geant/nmaas/portal/api/bulk/BulkController.java
index ea7f46dd5a5ff48e624aeb969fc10e06977a94fb..0ae731c41090c96fe7b03cdd9d897345af8382fd 100644
--- a/src/main/java/net/geant/nmaas/portal/api/bulk/BulkController.java
+++ b/src/main/java/net/geant/nmaas/portal/api/bulk/BulkController.java
@@ -181,6 +181,18 @@ public class BulkController {
                 .collect(Collectors.toList());
     }
 
+    @GetMapping("/refresh/{id}")
+    @PreAuthorize("hasRole('ROLE_SYSTEM_ADMIN') || hasRole('ROLE_VL_MANAGER')")
+    public ResponseEntity<BulkDeploymentViewS> getRefreshedState(@PathVariable Long id) {
+        return ResponseEntity.ok(mapToView(this.bulkApplicationService.updateState(id)));
+    }
+
+    private List<BulkDeploymentViewS> mapToView(List<BulkDeployment> deployments) {
+        return deployments.stream()
+                .map(bulk -> mapToView(bulk, BulkDeploymentViewS.class))
+                .collect(Collectors.toList());
+    }
+
     private <T extends BulkDeploymentViewS> T mapToView(BulkDeployment bulk, Class<T> viewType) {
         T bulkView = modelMapper.map(bulk, viewType);
         bulkView.setCreator(getUserView(bulk.getCreatorId()));
@@ -188,6 +200,14 @@ public class BulkController {
         return bulkView;
     }
 
+    private BulkDeploymentView mapToView(BulkDeployment deployment) {
+        BulkDeploymentView bulkView = modelMapper.map(deployment, BulkDeploymentView.class);
+        bulkView.setCreator(getUserView(deployment.getCreatorId()));
+        mapDetails(deployment, bulkView);
+        return bulkView;
+
+    }
+
     private void mapDetails(BulkDeployment deployment, BulkDeploymentViewS view) {
         if (deployment.getType().equals(BulkType.APPLICATION)) {
             Map<String, String> details = new HashMap<>();
diff --git a/src/main/java/net/geant/nmaas/portal/service/BulkApplicationService.java b/src/main/java/net/geant/nmaas/portal/service/BulkApplicationService.java
index 656dcd11d86a55736201a081bac2c8e88c6d5c13..15c439137c55ac8b47e13419f3913835f439c351 100644
--- a/src/main/java/net/geant/nmaas/portal/service/BulkApplicationService.java
+++ b/src/main/java/net/geant/nmaas/portal/service/BulkApplicationService.java
@@ -7,6 +7,7 @@ import net.geant.nmaas.portal.api.bulk.BulkDeploymentView;
 import net.geant.nmaas.portal.api.bulk.BulkDeploymentViewS;
 import net.geant.nmaas.portal.api.bulk.CsvApplication;
 import net.geant.nmaas.portal.api.domain.UserViewMinimal;
+import net.geant.nmaas.portal.persistent.entity.BulkDeployment;
 import org.springframework.context.ApplicationEvent;
 import org.springframework.core.io.InputStreamResource;
 
@@ -26,4 +27,6 @@ public interface BulkApplicationService {
 
     void deleteAppInstancesFromBulk(BulkDeploymentView bulk);
 
+    BulkDeployment updateState(Long bulkId);
+
 }
diff --git a/src/main/java/net/geant/nmaas/portal/service/impl/BulkApplicationServiceImpl.java b/src/main/java/net/geant/nmaas/portal/service/impl/BulkApplicationServiceImpl.java
index 8efe9388d045dca0ad459e0abb45f42a549db0f0..c7e5ae6c4e48444cbad6f0a98572e4b3b82895a4 100644
--- a/src/main/java/net/geant/nmaas/portal/service/impl/BulkApplicationServiceImpl.java
+++ b/src/main/java/net/geant/nmaas/portal/service/impl/BulkApplicationServiceImpl.java
@@ -321,6 +321,57 @@ public class BulkApplicationServiceImpl implements BulkApplicationService {
                 .orElseThrow(() -> new ObjectNotFoundException(key + " not found"));
     }
 
+    @Override
+    public BulkDeployment updateState(Long bulkId) {
+        log.info("Update all states for bulk {}", bulkId);
+        Optional<BulkDeployment> bulk = this.bulkDeploymentRepository.findById(bulkId);
+        if(bulk.isPresent()) {
+            BulkDeployment bulkDeployment = bulk.get();
+            bulkDeployment.getEntries().forEach(entry -> {
+                try {
+                    Long instanceId = Long.valueOf(entry.getDetails().get(BULK_ENTRY_DETAIL_KEY_APP_INSTANCE_ID));
+                    AppInstance instance = instanceService.find(instanceId).orElseThrow();
+
+                    AppLifecycleState state = appDeploymentMonitor.state(instance.getInternalId());
+                    switch (state) {
+                        case APPLICATION_DEPLOYMENT_VERIFIED:
+                            entry.setState(BulkDeploymentState.COMPLETED);
+                            bulkDeploymentEntryRepository.save(entry);
+                            break;
+                        case APPLICATION_CONFIGURATION_FAILED:
+                        case APPLICATION_DEPLOYMENT_FAILED:
+                        case APPLICATION_DEPLOYMENT_VERIFICATION_FAILED:
+                        case INTERNAL_ERROR:
+                            entry.setState(BulkDeploymentState.FAILED);
+                            bulkDeploymentEntryRepository.save(entry);
+                            break;
+                        default:
+                            entry.setState(BulkDeploymentState.PENDING);
+                            bulkDeploymentEntryRepository.save(entry);
+                            break;
+                    }
+                    logBulkStateUpdate(entry.getId(), entry.getState().name());
+
+                } catch (Exception e) {
+                    log.error("Can not update state of {} bulk entry", entry.getId());
+                }
+            });
+            if (bulkDeployment.getEntries().stream().allMatch(e -> BulkDeploymentState.COMPLETED.equals(e.getState()))) {
+                bulkDeployment.setState(BulkDeploymentState.COMPLETED);
+            } else if (bulkDeployment.getEntries().stream().allMatch(e -> BulkDeploymentState.FAILED.equals(e.getState()))) {
+                bulkDeployment.setState(BulkDeploymentState.FAILED);
+            } else if (bulkDeployment.getEntries().stream().anyMatch(e -> BulkDeploymentState.FAILED.equals(e.getState()))) {
+                bulkDeployment.setState(BulkDeploymentState.PARTIALLY_FAILED);
+            }
+            logBulkStateUpdate(bulkDeployment.getId(),bulkDeployment.getState().name());
+            bulkDeploymentRepository.save(bulkDeployment);
+            return bulkDeployment;
+        } else {
+            log.error("Can not find bulk deployment {}", bulkId);
+            throw new MissingElementException("Can not find bulk deployment " + bulkId);
+        }
+    }
+
     private static BulkDeployment createBulkDeployment(UserViewMinimal creator) {
         BulkDeployment bulkDeployment = new BulkDeployment();
         bulkDeployment.setType(BulkType.APPLICATION);
diff --git a/src/test/shell/data/i18n/de.json b/src/test/shell/data/i18n/de.json
index 3f309f2c926862104bb0340f28259ea99d40545c..0f09b429bb63262468ec799db30a6e4427581819 100644
--- a/src/test/shell/data/i18n/de.json
+++ b/src/test/shell/data/i18n/de.json
@@ -1236,7 +1236,8 @@
       "DOMAIN" : "Domain",
       "CHECK_STATE" : "Check state",
       "UPLOAD_TEXT" : "or enter CSV content below",
-      "DOWNLOAD_CSV" : "Download CSV"
+      "DOWNLOAD_CSV" : "Download CSV",
+      "REFRESH" : "Refresh states"
     },
     "STATE" : {
       "PENDING" :  "Pending",
diff --git a/src/test/shell/data/i18n/en.json b/src/test/shell/data/i18n/en.json
index 93077028cf154bffb800cabf2c4f5fb69f59e8ad..8483d436679d2fdcd2a44b6124078ed3828afea6 100644
--- a/src/test/shell/data/i18n/en.json
+++ b/src/test/shell/data/i18n/en.json
@@ -1239,7 +1239,8 @@
       "DOMAIN" : "Domain",
       "CHECK_STATE" : "Check state",
       "UPLOAD_TEXT" : "or enter the csv content below",
-      "DOWNLOAD_CSV" : "Download CSV"
+      "DOWNLOAD_CSV" : "Download CSV",
+      "REFRESH" : "Refresh states"
     },
     "STATE" : {
       "PENDING" :  "Pending",
diff --git a/src/test/shell/data/i18n/fr.json b/src/test/shell/data/i18n/fr.json
index 2a7b0829c24d5b9040062136bf67d4990d553d79..44607c6f52d30ac1284be02e4ba70cc5d8829543 100644
--- a/src/test/shell/data/i18n/fr.json
+++ b/src/test/shell/data/i18n/fr.json
@@ -1237,7 +1237,8 @@
       "DOMAIN" : "Domain",
       "CHECK_STATE" : "Check state",
       "UPLOAD_TEXT" : "or enter CSV content below",
-      "DOWNLOAD_CSV" : "Download CSV"
+      "DOWNLOAD_CSV" : "Download CSV",
+      "REFRESH" : "Refresh states"
     },
     "STATE" : {
       "PENDING" :  "Pending",
diff --git a/src/test/shell/data/i18n/pl.json b/src/test/shell/data/i18n/pl.json
index 582f4fc7dbf733607010587d6212b4f59ee9262b..66b386afbbdd83cc8ab1e24fd034d58fd7ab3cea 100644
--- a/src/test/shell/data/i18n/pl.json
+++ b/src/test/shell/data/i18n/pl.json
@@ -1238,7 +1238,8 @@
       "DOMAIN" : "Domena",
       "CHECK_STATE" : "Sprawdź status",
       "UPLOAD_TEXT" : "lub podaj tekst w formacie CSV poniżej",
-      "DOWNLOAD_CSV" : "Pobierz CSV"
+      "DOWNLOAD_CSV" : "Pobierz CSV",
+      "REFRESH" : "Odśwież stany"
     },
     "STATE" : {
       "PENDING" :  "Oczekuje",