diff --git a/SAS/TMSS/src/remakemigrations.py b/SAS/TMSS/src/remakemigrations.py
index 6a4ee430ffd683388eb4c0ba5523dfc4d89d4c39..86d8f07c6e91a29cb8a89d67d06cd6c24a990411 100755
--- a/SAS/TMSS/src/remakemigrations.py
+++ b/SAS/TMSS/src/remakemigrations.py
@@ -75,6 +75,11 @@ class Migration(migrations.Migration):
 
     # Start SubTask id with 2 000 000 to avoid overlap with 'old' (test/production) OTDB
     operations = [ migrations.RunSQL('ALTER SEQUENCE tmssapp_SubTask_id_seq RESTART WITH 2000000;'),
+                   migrations.RunSQL('DROP VIEW IF EXISTS tmssapp_taskblueprintsummary; '
+                                     'CREATE OR REPLACE VIEW tmssapp_taskblueprintsummary AS '
+                                     'SELECT tmssapp_taskblueprint.id AS taskblueprint_id, tmssapp_subtask.id AS subtask_id, tmssapp_subtask.state_id AS substate, tmssapp_subtasktemplate.type_id AS subtask_type'
+                                     ' FROM tmssapp_subtask LEFT JOIN tmssapp_taskblueprint ON tmssapp_taskblueprint.id = tmssapp_subtask.task_blueprint_id'
+                                     ' LEFT JOIN tmssapp_subtasktemplate ON tmssapp_subtasktemplate.id = tmssapp_subtask.specifications_template_id;'),
                    migrations.RunPython(populate_choices),
                    migrations.RunPython(populate_settings),
                    migrations.RunPython(populate_misc),
diff --git a/SAS/TMSS/src/tmss/tmssapp/migrations/0002_populate.py b/SAS/TMSS/src/tmss/tmssapp/migrations/0002_populate.py
index 92baffd4c15a8c025d234eeffed61ae9f443fabf..89390eddeed337b2210f88f827034711f75a3a47 100644
--- a/SAS/TMSS/src/tmss/tmssapp/migrations/0002_populate.py
+++ b/SAS/TMSS/src/tmss/tmssapp/migrations/0002_populate.py
@@ -16,6 +16,11 @@ class Migration(migrations.Migration):
 
     # Start SubTask id with 2 000 000 to avoid overlap with 'old' (test/production) OTDB
     operations = [ migrations.RunSQL('ALTER SEQUENCE tmssapp_SubTask_id_seq RESTART WITH 2000000;'),
+                   migrations.RunSQL('DROP VIEW IF EXISTS tmssapp_taskblueprintsummary; '
+                                     'CREATE OR REPLACE VIEW tmssapp_taskblueprintsummary AS '
+                                     'SELECT tmssapp_taskblueprint.id AS taskblueprint_id, tmssapp_subtask.id AS subtask_id, tmssapp_subtask.state_id AS substate, tmssapp_subtasktemplate.type_id AS subtask_type'
+                                     ' FROM tmssapp_subtask LEFT JOIN tmssapp_taskblueprint ON tmssapp_taskblueprint.id = tmssapp_subtask.task_blueprint_id'
+                                     ' LEFT JOIN tmssapp_subtasktemplate ON tmssapp_subtasktemplate.id = tmssapp_subtask.specifications_template_id;'),
                    migrations.RunPython(populate_choices),
                    migrations.RunPython(populate_settings),
                    migrations.RunPython(populate_misc),
diff --git a/SAS/TMSS/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/src/tmss/tmssapp/models/specification.py
index 357a1ae43ab549751af1e48c70c9872e974491e8..9409d02ad795ebba42c6da85046af79f9cd6f710 100644
--- a/SAS/TMSS/src/tmss/tmssapp/models/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/models/specification.py
@@ -359,11 +359,25 @@ class DefaultTaskTemplate(BasicCommon):
 class TaskRelationSelectionTemplate(Template):
     pass
 
+
 class DefaultTaskRelationSelectionTemplate(BasicCommon):
     name = CharField(max_length=128, unique=True)
     template = ForeignKey("TaskRelationSelectionTemplate", on_delete=PROTECT)
 
 
+#
+# DatabaseView  objects
+#
+class TaskBlueprintSummary(Model):
+    taskblueprint_id = IntegerField()
+    subtask_id = IntegerField()
+    substate = CharField(max_length=128)
+    subtask_type = CharField(max_length=128)
+
+    class Meta:
+        managed = False
+        db_table = 'tmssapp_taskblueprintsummary'
+
 #
 # Instance Objects
 #
@@ -808,6 +822,36 @@ class TaskBlueprint(NamedCommon):
         else:
             return None
 
+    @property
+    def status(self):
+        """
+        Return the taskblueprint status which is derived from the subtasks status
+        See https://support.astron.nl/confluence/display/TMSS/Specification+Flow#SpecificationFlow-TaskBlueprints
+        The status is displayed as extra field in rest api of the taskblueprint
+        """
+        total_nbr_subtasks = self.subtasks.all().count()
+        total_nbr_observation_subtasks = TaskBlueprintSummary.objects.filter(taskblueprint_id=self.id, subtask_type='observation').count()
+
+        if total_nbr_subtasks == 0 or \
+                TaskBlueprintSummary.objects.filter(taskblueprint_id=self.id, substate='defining').count() > 0:
+            status = "defined"
+        elif TaskBlueprintSummary.objects.filter(taskblueprint_id=self.id, substate='finished').count() == total_nbr_subtasks:
+            status = "finished"
+        elif TaskBlueprintSummary.objects.filter(taskblueprint_id=self.id, substate__in=('cancelling','cancelled')).count() > 0:
+            status = "cancelled"
+        elif TaskBlueprintSummary.objects.filter(taskblueprint_id=self.id, substate='error').count() > 0:
+            status = "error"
+        elif TaskBlueprintSummary.objects.filter(taskblueprint_id=self.id, substate__in=('finishing','finished'), subtask_type='observation').count() == total_nbr_observation_subtasks \
+                and total_nbr_observation_subtasks > 0:
+            status = "observed"
+        elif TaskBlueprintSummary.objects.filter(taskblueprint_id=self.id, substate__in=('starting','started','queueing','queued','finishing','finished')).count() > 0:
+            status = "started"
+        elif TaskBlueprintSummary.objects.filter(taskblueprint_id=self.id, substate='scheduled').count() > 0:
+            status = "scheduled"
+        else:
+            status = "schedulable"
+        return status
+
 
 class TaskRelationDraft(BasicCommon):
     selection_doc = JSONField(help_text='Filter for selecting dataproducts from the output role.')
diff --git a/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py b/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py
index 951340e2ed08c9d6568579f58e5d10b062ec97c6..4ef2c8936688f0714e944b7f5a9af147dd3e34df 100644
--- a/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py
@@ -334,7 +334,8 @@ class TaskBlueprintSerializer(RelationalHyperlinkedModelSerializer):
     class Meta:
         model = models.TaskBlueprint
         fields = '__all__'
-        extra_fields = ['subtasks', 'produced_by', 'consumed_by', 'first_to_connect', 'second_to_connect', 'duration', 'start_time', 'stop_time', 'relative_start_time', 'relative_stop_time']
+        extra_fields = ['subtasks', 'produced_by', 'consumed_by', 'first_to_connect', 'second_to_connect', 'duration',
+                        'start_time', 'stop_time', 'relative_start_time', 'relative_stop_time', 'status']
 
 
 class TaskRelationDraftSerializer(RelationalHyperlinkedModelSerializer):
diff --git a/SAS/TMSS/test/t_subtasks.py b/SAS/TMSS/test/t_subtasks.py
index 17210063f2e24e31a19a3a1f05edee0375c409d7..ca94d9eb33be0377cbbd5aa1d3a3cb3623be411f 100755
--- a/SAS/TMSS/test/t_subtasks.py
+++ b/SAS/TMSS/test/t_subtasks.py
@@ -115,6 +115,8 @@ def create_scheduling_relation_task_blueprint_for_testing(first_task_blueprint,
                                  placement=models.SchedulingRelationPlacement.objects.get(value='before'),
                                  time_offset=60)
     return task_scheduling_rel_obj
+
+
 class SubTasksCreationFromSubTask(unittest.TestCase):
 
     def test_create_qafile_subtask_from_observation_subtask_failed(self):
diff --git a/SAS/TMSS/test/t_tasks.py b/SAS/TMSS/test/t_tasks.py
index ae878f68ad6712aab49ab8d974d4aa8a1416712f..498552d07bfe7776e3350e3f6617fd5988df60fc 100755
--- a/SAS/TMSS/test/t_tasks.py
+++ b/SAS/TMSS/test/t_tasks.py
@@ -255,6 +255,69 @@ class CreationFromTaskDraft(unittest.TestCase):
         self.assertEqual(0, task_blueprint.subtasks.count())
 
 
+class TaskBlueprintStateTest(unittest.TestCase):
+    """
+    Test the Task Blueprint State which is derived from the SubTask states.
+    The result of each possible combination of these states will be checked (using 2 subtasks)
+    See https://support.astron.nl/confluence/display/TMSS/Specification+Flow#SpecificationFlow-TaskBlueprints
+    """
+
+    def test_state_whith_no_subtasks(self):
+        """
+        Test the taskblueprint state when subtasks are not instantiated.
+        the expected state should be 'defined'
+        """
+        task_blueprint_data = TaskBlueprint_test_data(name="Task Blueprint No Subtasks")
+        task_blueprint = models.TaskBlueprint.objects.create(**task_blueprint_data)
+        self.assertEqual("defined", task_blueprint.status)
+
+    def test_states_with_observation_and_pipeline_subtask(self):
+        """
+        Test the taskblueprint state when two subtasks are instantiated, an observation and a pipeline.
+        See next table where every row represents:
+          Substate(Obs), Substate(Pipeline), Expected TaskBlueprint State
+        """
+        test_table = [
+            ("defining",    "defining",   "defined"),
+            ("defining",    "defined",    "defined"),
+            ("defined",     "defined",    "schedulable"),
+            ("scheduling",  "defined",    "schedulable"),
+            ("scheduled",   "defined",    "scheduled"),
+            ("starting",    "defined",    "started"),
+            ("started",     "defined",    "started"),
+            ("queueing",    "defined",    "started"),
+            ("queued",      "defined",    "started"),
+            ("finishing",   "defined",    "observed"),
+            ("finished",    "defined",    "observed"),
+            ("defined",     "finishing",  "started"),  # The difference is here ...not observed
+            ("defined",     "finished",   "started"),  # The difference is here ...not observed
+            ("finished",    "finished",   "finished"),
+            ("cancelling",  "defined",    "cancelled"),
+            ("cancelled",   "defined",    "cancelled"),
+            ("error",       "defined",    "error")
+        ]
+        # Create taskblueprint
+        task_blueprint_data = TaskBlueprint_test_data(name="Task Blueprint With Subtasks")
+        task_blueprint = models.TaskBlueprint.objects.create(**task_blueprint_data)
+        # Create observation and pipeline subtask related to taskblueprint
+        subtask_data = Subtask_test_data(task_blueprint, state=models.SubtaskState.objects.get(value="defined"),
+                                         subtask_template=models.SubtaskTemplate.objects.get(name='observation control'))
+        subtask_obs = models.Subtask.objects.create(**subtask_data)
+        subtask_data = Subtask_test_data(task_blueprint, state=models.SubtaskState.objects.get(value="defined"),
+                                         subtask_template=models.SubtaskTemplate.objects.get(name='pipeline control'))
+        subtask_pipe = models.Subtask.objects.create(**subtask_data)
+
+        # Do the actual test
+        for test_item in test_table:
+            state_obs, state_pipe, expected_task_state = test_item
+            logger.info("Expected test result of substates observation='%s' and pipeline='%s' should be '%s'" % (state_obs, state_pipe, expected_task_state))
+            subtask_obs.state = models.SubtaskState.objects.get(value=state_obs)
+            subtask_obs.save()
+            subtask_pipe.state = models.SubtaskState.objects.get(value=state_pipe)
+            subtask_pipe.save()
+            self.assertEqual(expected_task_state, task_blueprint.status)
+
+
 if __name__ == "__main__":
     os.environ['TZ'] = 'UTC'
     unittest.main()