diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py
index a89b16fc3d51aaf571122805d7ccde6d3ae46213..2fffaacce2860830ce8cf931ccb535535ae69121 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/migrations/0001_initial.py
@@ -1,4 +1,4 @@
-# Generated by Django 3.0.9 on 2021-03-22 10:34
+# Generated by Django 3.0.9 on 2021-03-23 17:08
 
 from django.conf import settings
 import django.contrib.postgres.fields
@@ -360,6 +360,15 @@ class Migration(migrations.Migration):
                 'abstract': False,
             },
         ),
+        migrations.CreateModel(
+            name='IOType',
+            fields=[
+                ('value', models.CharField(max_length=128, primary_key=True, serialize=False, unique=True)),
+            ],
+            options={
+                'abstract': False,
+            },
+        ),
         migrations.CreateModel(
             name='PeriodCategory',
             fields=[
@@ -464,13 +473,13 @@ class Migration(migrations.Migration):
             name='ReservationStrategyTemplate',
             fields=[
                 ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
-                ('tags',django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, help_text='User-defined search keywords for object.', size=8)),
+                ('tags', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, help_text='User-defined search keywords for object.', size=8)),
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
                 ('name', models.CharField(help_text='Human-readable name of this object.', max_length=128)),
                 ('description', models.CharField(blank=True, default='', help_text='A longer description of this object.', max_length=255)),
                 ('version', models.CharField(help_text='Version of this template (with respect to other templates of the same name).', max_length=128)),
-                ('template', django.contrib.postgres.fields.jsonb.JSONField(help_text='JSON-data compliant with the JSON-schema in the scheduling_unit_template. This observation strategy template like a predefined recipe with all the correct settings, and defines which parameters the user can alter.')),
+                ('template', django.contrib.postgres.fields.jsonb.JSONField(help_text='JSON-data compliant with the JSON-schema in the reservation_template. This reservation strategy template like a predefined recipe with all the correct settings, and defines which parameters the user can alter.')),
             ],
             options={
                 'abstract': False,
@@ -790,7 +799,6 @@ class Migration(migrations.Migration):
                 ('tags', django.contrib.postgres.fields.ArrayField(base_field=models.CharField(max_length=128), blank=True, default=list, help_text='User-defined search keywords for object.', size=8)),
                 ('created_at', models.DateTimeField(auto_now_add=True, help_text='Moment of object creation.')),
                 ('updated_at', models.DateTimeField(auto_now=True, help_text='Moment of last object update.')),
-                ('output', models.BooleanField(help_text='True if this connector describes an output, False if this connector describes an input')),
             ],
             options={
                 'abstract': False,
@@ -1011,6 +1019,11 @@ class Migration(migrations.Migration):
             name='datatype',
             field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='tmssapp.Datatype'),
         ),
+        migrations.AddField(
+            model_name='taskconnectortype',
+            name='iotype',
+            field=models.ForeignKey(help_text='Is this connector an input or output', on_delete=django.db.models.deletion.PROTECT, to='tmssapp.IOType'),
+        ),
         migrations.AddField(
             model_name='taskconnectortype',
             name='role',
@@ -1235,12 +1248,12 @@ class Migration(migrations.Migration):
         migrations.AddField(
             model_name='projectquotaarchivelocation',
             name='project_quota',
-            field=models.ForeignKey(help_text='Project to which this quota belongs.', on_delete=django.db.models.deletion.PROTECT, related_name='project_quota', to='tmssapp.ProjectQuota'),
+            field=models.ForeignKey(help_text='The ProjectQuota for this archive location', on_delete=django.db.models.deletion.PROTECT, related_name='project_quota_archive_location', to='tmssapp.ProjectQuota'),
         ),
         migrations.AddField(
             model_name='projectquota',
             name='project',
-            field=models.ForeignKey(help_text='Project to which this quota belongs.', on_delete=django.db.models.deletion.PROTECT, related_name='quota', to='tmssapp.Project'),
+            field=models.ForeignKey(help_text='Project to wich this quota belongs.', on_delete=django.db.models.deletion.PROTECT, related_name='quota', to='tmssapp.Project'),
         ),
         migrations.AddField(
             model_name='projectquota',
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
index 2ebdaf12e1bb2f89b818da644773373ba697da99..be5b44b7cbfaa585cb2ca08cd6b7e9dbfd4daa60 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/models/specification.py
@@ -55,6 +55,15 @@ class Role(AbstractChoice):
         ANY = "any"
 
 
+class IOType(AbstractChoice):
+    """Defines the model and predefined list of possible IOType's for TaskConnectorType.
+    The items in the Choises class below are automagically populated into the database via a data migration."""
+    class Choices(Enum):
+        INPUT = "input"
+        OUTPUT = "output"
+        # maybe we can add an IN_PLACE="in_place" option in the future, but for now it's not needed.
+
+
 class Datatype(AbstractChoice):
     """Defines the model and predefined list of possible Datatype's for TaskConnectorType.
     The items in the Choises class below are automagically populated into the database via a data migration."""
@@ -163,7 +172,7 @@ class TaskConnectorType(BasicCommon):
     datatype = ForeignKey('Datatype', null=False, on_delete=PROTECT)
     dataformats = ManyToManyField('Dataformat', blank=True)
     task_template = ForeignKey("TaskTemplate", related_name='output_connector_types', null=False, on_delete=CASCADE)
-    output = BooleanField(null=False, help_text="True if this connector describes an output, False if this connector describes an input")
+    iotype = ForeignKey('IOType', null=False, on_delete=PROTECT, help_text="Is this connector an input or output")
 
 
 #
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/populate.py b/SAS/TMSS/backend/src/tmss/tmssapp/populate.py
index 43d73566a0ff3de217ac61dba88354a548f5a0b4..4d274999457d157af50a67241c65a213a791a2bb 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/populate.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/populate.py
@@ -40,7 +40,7 @@ def populate_choices(apps, schema_editor):
     each 'choice'type in Role, Datatype, Dataformat, CopyReason
     :return: None
     '''
-    choice_classes = [Role, Datatype, Dataformat, CopyReason,
+    choice_classes = [Role, IOType, Datatype, Dataformat, CopyReason,
                       SubtaskState, SubtaskType, StationType, Algorithm, SchedulingRelationPlacement,
                       Flag, ProjectCategory, PeriodCategory, Quantity, TaskType, ProjectRole]
 
@@ -359,35 +359,35 @@ def populate_connectors():
     TaskConnectorType.objects.create(role=Role.objects.get(value=Role.Choices.CORRELATOR.value),
                                  datatype=Datatype.objects.get(value=Datatype.Choices.VISIBILITIES.value),
                                  task_template=TaskTemplate.objects.get(name='calibrator observation'),
-                                 output=True)
+                                 iotype=IOType.objects.get(value=IOType.Choices.OUTPUT.value))
 
     # target observation
     TaskConnectorType.objects.create(role=Role.objects.get(value=Role.Choices.CORRELATOR.value),
                                  datatype=Datatype.objects.get(value=Datatype.Choices.VISIBILITIES.value),
                                  task_template=TaskTemplate.objects.get(name='target observation'),
-                                 output=True)
+                                 iotype=IOType.objects.get(value=IOType.Choices.OUTPUT.value))
 
     # preprocessing pipeline
     TaskConnectorType.objects.create(role=Role.objects.get(value=Role.Choices.ANY.value),
                                  datatype=Datatype.objects.get(value=Datatype.Choices.VISIBILITIES.value),
                                  task_template=TaskTemplate.objects.get(name='preprocessing pipeline'),
-                                 output=False)
+                                 iotype=IOType.objects.get(value=IOType.Choices.INPUT.value))
 
     TaskConnectorType.objects.create(role=Role.objects.get(value=Role.Choices.ANY.value),
                                  datatype=Datatype.objects.get(value=Datatype.Choices.VISIBILITIES.value),
                                  task_template=TaskTemplate.objects.get(name='preprocessing pipeline'),
-                                 output=True)
+                                 iotype=IOType.objects.get(value=IOType.Choices.OUTPUT.value))
 
     # ingest
     TaskConnectorType.objects.create(role=Role.objects.get(value=Role.Choices.ANY.value),
                                  datatype=Datatype.objects.get(value=Datatype.Choices.VISIBILITIES.value),
                                  task_template=TaskTemplate.objects.get(name='ingest'),
-                                 output=False)
+                                 iotype=IOType.objects.get(value=IOType.Choices.INPUT.value))
 
     TaskConnectorType.objects.create(role=Role.objects.get(value=Role.Choices.ANY.value),
                                  datatype=Datatype.objects.get(value=Datatype.Choices.TIME_SERIES.value),
                                  task_template=TaskTemplate.objects.get(name='ingest'),
-                                 output=False)
+                                 iotype=IOType.objects.get(value=IOType.Choices.INPUT.value))
 
 
 def populate_permissions():
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/serializers/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/serializers/specification.py
index 47086104958108a4cc364a1c07c84c200d909d64..8e21947208819f013ba1c7d23bda3586cd774f91 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/serializers/specification.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/serializers/specification.py
@@ -102,6 +102,11 @@ class RoleSerializer(serializers.ModelSerializer):
         model = models.Role
         fields = '__all__'
 
+class IOTypeSerializer(serializers.ModelSerializer):
+    class Meta:
+        model = models.IOType
+        fields = '__all__'
+
 class SchedulingRelationPlacementSerializer(serializers.ModelSerializer):
     class Meta:
         model = models.SchedulingRelationPlacement
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/tasks.py b/SAS/TMSS/backend/src/tmss/tmssapp/tasks.py
index 0752147c4e54e0d5f9caa67c16ecc374a8adf7a0..e6d9c06ebe4e38f60a459788c6d16f41569b237c 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/tasks.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/tasks.py
@@ -179,8 +179,8 @@ def create_task_drafts_from_scheduling_unit_draft(scheduling_unit_draft: models.
         producer_task_draft = scheduling_unit_draft.task_drafts.get(name=task_relation_definition["producer"])
         consumer_task_draft = scheduling_unit_draft.task_drafts.get(name=task_relation_definition["consumer"])
         dataformat = models.Dataformat.objects.get(value=task_relation_definition["dataformat"])
-        input_role = models.TaskConnectorType.objects.get(task_template=consumer_task_draft.specifications_template, role=task_relation_definition["input"]["role"], datatype=task_relation_definition["input"]["datatype"], output=False)
-        output_role = models.TaskConnectorType.objects.get(task_template=producer_task_draft.specifications_template, role=task_relation_definition["output"]["role"], datatype=task_relation_definition["output"]["datatype"], output=True)
+        input_role = models.TaskConnectorType.objects.get(task_template=consumer_task_draft.specifications_template, role=task_relation_definition["input"]["role"], datatype=task_relation_definition["input"]["datatype"], iotype=models.IOType.objects.get(value=models.IOType.Choices.INPUT.value))
+        output_role = models.TaskConnectorType.objects.get(task_template=producer_task_draft.specifications_template, role=task_relation_definition["output"]["role"], datatype=task_relation_definition["output"]["datatype"], iotype=models.IOType.objects.get(value=models.IOType.Choices.OUTPUT.value))
         selection_template = models.TaskRelationSelectionTemplate.objects.get(name=task_relation_definition["selection_template"])
 
         try:
diff --git a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py
index d53ace784b028f01ba199a80e067090526a66a41..620742eaa77f9aedd8400e88f862121fcb2e2dbf 100644
--- a/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py
+++ b/SAS/TMSS/backend/src/tmss/tmssapp/viewsets/specification.py
@@ -280,6 +280,11 @@ class RoleViewSet(LOFARViewSet):
     serializer_class = serializers.RoleSerializer
 
 
+class IOTypeViewSet(LOFARViewSet):
+    queryset = models.IOType.objects.all()
+    serializer_class = serializers.IOTypeSerializer
+
+
 class SchedulingRelationPlacement(LOFARViewSet):
     queryset = models.SchedulingRelationPlacement.objects.all()
     serializer_class = serializers.SchedulingRelationPlacementSerializer
diff --git a/SAS/TMSS/backend/src/tmss/urls.py b/SAS/TMSS/backend/src/tmss/urls.py
index 66e58162725f917a20c5020e6492ad6f39bed7d0..afe222f05f2ef50547b85a34cd591755dbd77c40 100644
--- a/SAS/TMSS/backend/src/tmss/urls.py
+++ b/SAS/TMSS/backend/src/tmss/urls.py
@@ -117,6 +117,7 @@ router.register(r'tags', viewsets.TagsViewSet)
 
 # choices
 router.register(r'role', viewsets.RoleViewSet)
+router.register(r'iotype', viewsets.IOTypeViewSet)
 router.register(r'datatype', viewsets.DatatypeViewSet)
 router.register(r'dataformat', viewsets.DataformatViewSet)
 router.register(r'copy_reason', viewsets.CopyReasonViewSet)
diff --git a/SAS/TMSS/backend/test/tmss_test_data_django_models.py b/SAS/TMSS/backend/test/tmss_test_data_django_models.py
index 2a6c110bc7fd857e9706c061d9b7c237b924cd4a..08c549f734feed11c0cda5fe64edd974297cb0af 100644
--- a/SAS/TMSS/backend/test/tmss_test_data_django_models.py
+++ b/SAS/TMSS/backend/test/tmss_test_data_django_models.py
@@ -107,7 +107,7 @@ def TaskConnectorType_test_data() -> dict:
     return {"role": models.Role.objects.get(value='calibrator'),
             "datatype": models.Datatype.objects.get(value='instrument model'),
             "task_template": models.TaskTemplate.objects.create(**TaskTemplate_test_data()),
-            "output": True,
+            "iotype": models.IOType.objects.get(value=models.IOType.Choices.OUTPUT.value),
             "tags": []}
 
 def Cycle_test_data() -> dict:
diff --git a/SAS/TMSS/backend/test/tmss_test_data_rest.py b/SAS/TMSS/backend/test/tmss_test_data_rest.py
index 340b365afe6f116d668e92ba6f31256cd64bb523..759885c6f84320b6f452ade940b1db2bfe8e4eb5 100644
--- a/SAS/TMSS/backend/test/tmss_test_data_rest.py
+++ b/SAS/TMSS/backend/test/tmss_test_data_rest.py
@@ -221,7 +221,7 @@ class TMSSRESTTestDataCreator():
             return self._task_relation_selection_template_url
 
 
-    def TaskConnectorType(self, role="correlator", output=True, task_template_url=None):
+    def TaskConnectorType(self, role="correlator", iotype="output", task_template_url=None):
         if task_template_url is None:
             task_template_url = self.cached_task_template_url
     
@@ -229,7 +229,7 @@ class TMSSRESTTestDataCreator():
                 "datatype": self.django_api_url + '/datatype/image',
                 "dataformats": [self.django_api_url + '/dataformat/Beamformed'],
                 "task_template": task_template_url,
-                "output": output,
+                "iotype": self.django_api_url + '/iotype/%s'%iotype,
                 "tags": []}
 
 
@@ -431,10 +431,10 @@ class TMSSRESTTestDataCreator():
             selection_doc = self.get_response_as_json_object(template_url+'/default')
 
         if input_role_url is None:
-            input_role_url = self.post_data_and_get_url(self.TaskConnectorType(output=False), '/task_connector_type/')
+            input_role_url = self.post_data_and_get_url(self.TaskConnectorType(iotype="input"), '/task_connector_type/')
     
         if output_role_url is None:
-            output_role_url = self.post_data_and_get_url(self.TaskConnectorType(output=True), '/task_connector_type/')
+            output_role_url = self.post_data_and_get_url(self.TaskConnectorType(iotype="output"), '/task_connector_type/')
     
         return {"tags": [],
                 "selection_doc": selection_doc,
@@ -530,10 +530,10 @@ class TMSSRESTTestDataCreator():
             selection_doc = self.get_response_as_json_object(template_url+'/default')
 
         if input_role_url is None:
-            input_role_url = self.post_data_and_get_url(self.TaskConnectorType(output=False), '/task_connector_type/')
+            input_role_url = self.post_data_and_get_url(self.TaskConnectorType(iotype="input"), '/task_connector_type/')
     
         if output_role_url is None:
-            output_role_url = self.post_data_and_get_url(self.TaskConnectorType(output=True), '/task_connector_type/')
+            output_role_url = self.post_data_and_get_url(self.TaskConnectorType(iotype="output"), '/task_connector_type/')
     
         # test data
         return {"tags": [],