diff --git a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
index b04ecd0b93b65653a7426a081eb419c03ddef895..81e15db2fa25ddd0d68245ed2d78273a47ccf76e 100644
--- a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
+++ b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py
@@ -690,6 +690,16 @@ class Migration(migrations.Migration):
                 ('validation_code_js', models.CharField(help_text='JavaScript code for additional (complex) validation.', max_length=128)),
             ],
         ),
+        migrations.CreateModel(
+            name='TaskType',
+            fields=[
+                ('value', models.CharField(max_length=128, primary_key=True, serialize=False, unique=True)),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
+
         migrations.CreateModel(
             name='Setting',
             fields=[
@@ -707,6 +717,11 @@ class Migration(migrations.Migration):
             model_name='tasktemplate',
             constraint=models.UniqueConstraint(fields=('name', 'version'), name='TaskTemplate_unique_name_version'),
         ),
+        migrations.AddField(
+            model_name='tasktemplate',
+            name='type',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tmssapp.TaskType'),
+        ),
         migrations.AddField(
             model_name='taskschedulingrelationdraft',
             name='first',
diff --git a/SAS/TMSS/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/src/tmss/tmssapp/models/specification.py
index 60b95bb0dff878b3b8eaa70606b9ad551eedcc71..26683b2cde8f68b1bb5944f8696d0aa09b905f30 100644
--- a/SAS/TMSS/src/tmss/tmssapp/models/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/models/specification.py
@@ -187,6 +187,17 @@ class ProjectCategory(AbstractChoice):
         TEST = "test"
 
 
+class TaskType(AbstractChoice):
+    """Defines the model and predefined list of possible TaskType's for Task.
+    The items in the Choices class below are automagically populated into the database via a data migration."""
+    class Choices(Enum):
+        OBSERVATION = "observation"
+        PIPELINE = "pipeline"
+        INGEST = "ingest"
+        MAINTENANCE = "maintenance"
+        OTHER = 'other'
+
+
 # concrete models
 
 class Setting(BasicCommon):
@@ -199,7 +210,7 @@ class TaskConnectorType(BasicCommon):
     datatype = ForeignKey('Datatype', null=False, on_delete=PROTECT)
     dataformats = ManyToManyField('Dataformat', blank=True)
     output_of = ForeignKey("TaskTemplate", related_name='output_connector_types', on_delete=CASCADE)
-    input_of = ForeignKey("TaskTemplate", related_name='inpput_connector_types', on_delete=CASCADE)
+    input_of = ForeignKey("TaskTemplate", related_name='input_connector_types', on_delete=CASCADE)
 
 
 #
@@ -245,6 +256,7 @@ class DefaultSchedulingUnitTemplate(BasicCommon):
 
 class TaskTemplate(Template):
     validation_code_js = CharField(max_length=128, help_text='JavaScript code for additional (complex) validation.')
+    type = ForeignKey('TaskType', null=False, on_delete=PROTECT)
 
     class Meta:
         # TODO: move up to the abstract base class and replace with django 3.0 UniqueConstraint(... name='%*class)s_unique_name_version)
diff --git a/SAS/TMSS/src/tmss/tmssapp/populate.py b/SAS/TMSS/src/tmss/tmssapp/populate.py
index c2ebe1653cebb47ded5a4fde25114d5ea533edeb..8de5dc5f2d0bee9de048b37ae94630d3006a83cf 100644
--- a/SAS/TMSS/src/tmss/tmssapp/populate.py
+++ b/SAS/TMSS/src/tmss/tmssapp/populate.py
@@ -37,7 +37,7 @@ def populate_choices(apps, schema_editor):
     '''
     for choice_class in [Role, Datatype, Dataformat, CopyReason,
                          SubtaskState, SubtaskType, StationType, Algorithm, ScheduleMethod, SchedulingRelationPlacement,
-                         Flag, ProjectCategory, PeriodCategory, Quantity]:
+                         Flag, ProjectCategory, PeriodCategory, Quantity, TaskType]:
         choice_class.objects.bulk_create([choice_class(value=x.value) for x in choice_class.Choices])
 
 def populate_settings(apps, schema_editor):
@@ -272,6 +272,7 @@ def _populate_observation_with_stations_schema():
     with open(os.path.join(working_dir, "schemas/task-observation-with-stations.json")) as json_file:
         json_data = json.loads(json_file.read())
         task_template_data = {"name": "observation schema",
+                              "type": TaskType.objects.get(value='observation'),
                               "description": 'schema for observations',
                               "version": '0.1',
                               "tags": [],
@@ -283,6 +284,7 @@ def _populate_calibrator_addon_schema():
     with open(os.path.join(working_dir, "schemas/task-calibrator-addon.json")) as json_file:
         json_data = json.loads(json_file.read())
         task_template_data = {"name": "calibrator schema",
+                              "type": TaskType.objects.get(value='observation'),
                               "description": 'addon schema for calibrator observations',
                               "version": '0.1',
                               "tags": [],
@@ -414,6 +416,7 @@ def _populate_preprocessing_schema():
     with open(os.path.join(working_dir, "schemas/task-preprocessing.json")) as json_file:
         json_data = json.loads(json_file.read())
         task_template_data = {"name": "preprocessing schema",
+                              "type": TaskType.objects.get(value='pipeline'),
                               "description": 'preprocessing settings',
                               "version": '0.1',
                               "tags": [],
diff --git a/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py b/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py
index f034bc0acc0376ba2725c25c28f04e5f4ce56d90..0e173fff9865a917e28757e03e1bd8cb0ecd6e52 100644
--- a/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/serializers/specification.py
@@ -380,5 +380,8 @@ class TaskSchedulingRelationBlueprintSerializer(RelationalHyperlinkedModelSerial
         fields = '__all__'
 
 
-
+class TaskTypeSerializer(RelationalHyperlinkedModelSerializer):
+    class Meta:
+        model = models.TaskType
+        fields = '__all__'
 
diff --git a/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py b/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py
index aa83ab8741ce9925bea917e6023c8af8bf8d3204..4404f40d6265ef41461d8c6db5f2ee114c0e2f03 100644
--- a/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py
+++ b/SAS/TMSS/src/tmss/tmssapp/viewsets/specification.py
@@ -605,3 +605,8 @@ class TaskRelationBlueprintNestedViewSet(LOFARNestedViewSet):
             return task_relation_draft.related_task_relation_blueprint.all()
         else:
             return models.TaskRelationBlueprint.objects.all()
+
+
+class TaskTypeViewSet(LOFARViewSet):
+    queryset = models.TaskType.objects.all()
+    serializer_class = serializers.TaskTypeSerializer
\ No newline at end of file
diff --git a/SAS/TMSS/src/tmss/urls.py b/SAS/TMSS/src/tmss/urls.py
index 6f9ea2167eb13acb6c3bf8dc330a07fe806881a2..35696e914d1a97e0b128ec796ad411c9f0b2cf36 100644
--- a/SAS/TMSS/src/tmss/urls.py
+++ b/SAS/TMSS/src/tmss/urls.py
@@ -90,6 +90,7 @@ router.register(r'flag', viewsets.FlagViewSet)
 router.register(r'period_category', viewsets.PeriodCategoryViewSet)
 router.register(r'project_category', viewsets.ProjectCategoryViewSet)
 router.register(r'quantity', viewsets.QuantityViewSet)
+router.register(r'task_type', viewsets.TaskTypeViewSet)
 
 # templates
 router.register(r'generator_template', viewsets.GeneratorTemplateViewSet)
diff --git a/SAS/TMSS/test/t_tmssapp_specification_REST_API.py b/SAS/TMSS/test/t_tmssapp_specification_REST_API.py
index bc95e9ccebc694054c9bdc87772d8b5aab58e0bb..9e8b6ee34df23d70887d4fa69a865ebc05f32596 100755
--- a/SAS/TMSS/test/t_tmssapp_specification_REST_API.py
+++ b/SAS/TMSS/test/t_tmssapp_specification_REST_API.py
@@ -216,7 +216,7 @@ class TaskTemplateTestCase(unittest.TestCase):
         test_data = test_data_creator.TaskTemplate()
         r_dict = POST_and_assert_expected_response(self, BASE_URL + '/task_template/', test_data, 201, test_data)
         url = r_dict['url']
-        GET_OK_and_assert_equal_expected_response(self, url + '?format=json', test_data)
+        GET_OK_and_assert_equal_expected_response(self, url, test_data)
 
     def test_task_template_PUT_invalid_raises_error(self):
         test_data = test_data_creator.TaskTemplate()
@@ -269,6 +269,27 @@ class TaskTemplateTestCase(unittest.TestCase):
         GET_OK_and_assert_equal_expected_response(self, BASE_URL + '/task_template/' + str(id1), test_data_1)
         GET_OK_and_assert_equal_expected_response(self, BASE_URL + '/task_template/' + str(id2), test_data_2)
 
+    def test_task_template_PROTECT_behavior_on_type_choice_deleted(self):
+        st_test_data = test_data_creator.TaskTemplate()
+
+        # create dependency that is safe to delete (enums are not populated / re-established between tests)
+        type_data = {'value': 'kickme'}
+        POST_and_assert_expected_response(self, BASE_URL + '/task_type/', type_data, 201, type_data)
+        type_url =  BASE_URL + '/task_type/kickme/'
+
+        # POST new item and verify
+        test_data = dict(st_test_data)
+        test_data['type'] = type_url
+        url = POST_and_assert_expected_response(self, BASE_URL + '/task_template/', test_data, 201, test_data)['url']
+        GET_OK_and_assert_equal_expected_response(self, url, test_data)
+
+        # Try to DELETE dependency, verify that was not successful
+        # Unfortunately we don't get a nice error in json, but a Django debug page on error 500...
+        response = requests.delete(type_url, auth=AUTH)
+        self.assertEqual(500, response.status_code)
+        self.assertTrue("ProtectedError" in str(response.content))
+        GET_OK_and_assert_equal_expected_response(self, type_url, type_data)
+
 
 class TaskRelationSelectionTemplateTestCase(unittest.TestCase):
     def test_task_relation_selection_template_list_apiformat(self):
diff --git a/SAS/TMSS/test/tmss_test_data_django_models.py b/SAS/TMSS/test/tmss_test_data_django_models.py
index 21ee23b0d2e0330a9a7660f91a2e8e3c72b9f66a..9ad9f6b8432496d871087b752786cbd371121357 100644
--- a/SAS/TMSS/test/tmss_test_data_django_models.py
+++ b/SAS/TMSS/test/tmss_test_data_django_models.py
@@ -64,12 +64,13 @@ def TaskTemplate_test_data(name="my TaskTemplate", version:str=None) -> dict:
     if version is None:
         version = str(uuid.uuid4())
 
-    return  {"validation_code_js":"",
-              "name": name,
-              "description": 'My TaskTemplate description',
-              "version": version,
-              "schema": {"mykey": "my value"},
-              "tags": ["TMSS", "TESTING"]}
+    return {"type": models.TaskType.objects.get(value='observation'),
+            "validation_code_js":"",
+            "name": name,
+            "description": 'My TaskTemplate description',
+            "version": version,
+            "schema": {"mykey": "my value"},
+            "tags": ["TMSS", "TESTING"]}
 
 def TaskRelationSelectionTemplate_test_data(name="my_TaskRelationSelectionTemplate", version:str=None) -> dict:
     if version is None:
diff --git a/SAS/TMSS/test/tmss_test_data_rest.py b/SAS/TMSS/test/tmss_test_data_rest.py
index a58cb44b97138e26ba08b4e08c379590dabb089f..765910ff9ab15d675060ac0586ad04d848de4c9f 100644
--- a/SAS/TMSS/test/tmss_test_data_rest.py
+++ b/SAS/TMSS/test/tmss_test_data_rest.py
@@ -81,15 +81,19 @@ class TMSSRESTTestDataCreator():
                  "schema": {"mykey": "my value"},
                  "tags": ["TMSS", "TESTING"]}
     
-    def TaskTemplate(self, name="tasktemplate1", version:str=None) -> dict:
+    def TaskTemplate(self, name="tasktemplate1", task_type_url:str=None, version:str=None) -> dict:
         if version is None:
             version = str(uuid.uuid4())
 
+        if task_type_url is None:
+            task_type_url = self.django_api_url + '/task_type/observation/'
+
         return {"name": name,
                 "description": 'My one observation',
                 "version": version,
                 "schema": {"mykey": "my value"},
                 "tags": ["TMSS", "TESTING"],
+                "type": task_type_url,
                 "validation_code_js": "???"}
     
     def TaskRelationSelectionTemplate(self, name="taskrelationselectiontemplate1", version:str=None) -> dict: