diff --git a/common_lib/graphql/__init__.py b/common_lib/graphql/__init__.py
index b301d078b31feefbfcc43fc9d80578c40f475cb6..5e2cd30e6434a3d61d2cf738f7e1d88862eb3c93 100644
--- a/common_lib/graphql/__init__.py
+++ b/common_lib/graphql/__init__.py
@@ -4,7 +4,6 @@ from .queries import (
     ExerciseIdAction,
     EmailThreadsAction,
     TeamActionLogsAction,
-    TeamInjectSelectionAction,
     ExtendedTeamToolsAction,
     ExerciseConfigAction,
     UsersAction,
diff --git a/common_lib/graphql/fragments.py b/common_lib/graphql/fragments.py
index dbd5ded740eeec63b673cbc381f19b72d41aa616..878c3c22a9858d3b448886222044f3ea46513aa6 100644
--- a/common_lib/graphql/fragments.py
+++ b/common_lib/graphql/fragments.py
@@ -63,17 +63,6 @@ class Fragments:
             {},
         )
 
-    @staticmethod
-    def inject_option() -> ResponseField:
-        return ResponseField(["id", "name", "sender", "content"], {})
-
-    @staticmethod
-    def inject_selection() -> ResponseField:
-        return ResponseField(
-            ["id", "name", "optionEmail", "timestamp"],
-            {"team": Fragments.team(), "options": Fragments.inject_option()},
-        )
-
     @staticmethod
     def email_template() -> ResponseField:
         return ResponseField(
@@ -97,9 +86,9 @@ class Fragments:
         )
 
     @staticmethod
-    def category() -> ResponseField:
+    def inject() -> ResponseField:
         return ResponseField(
-            ["id", "name", "auto", "email", "time", "delay", "organization"], {}
+            ["id", "name", "email", "time", "delay", "organization"], {}
         )
 
     @staticmethod
diff --git a/common_lib/graphql/queries.py b/common_lib/graphql/queries.py
index b182bf44b845e01b62ce92786c9e04865706ee06..18a71397407231b94d0cb8b67458c6ee8ae7eebb 100644
--- a/common_lib/graphql/queries.py
+++ b/common_lib/graphql/queries.py
@@ -27,19 +27,6 @@ class ExerciseIdAction(APIAction):
         )
 
 
-class TeamInjectSelectionAction(APIAction):
-    query_name = "teamInjectSelections"
-
-    def __init__(self, variables: Dict[str, Any]):
-        self.variables = variables
-        self.query = GraphQLQuery(
-            "query",
-            self.query_name,
-            [id_argument("team")],
-            Fragments.inject_selection(),
-        )
-
-
 class EmailThreadsAction(APIAction):
     query_name = "emailThreads"
 
diff --git a/common_lib/schema_types.py b/common_lib/schema_types.py
index 1068392c062842b4b18f90c091f4f52779b40869..b84f967bc853d0be576d1cb52802809e49c0f88c 100644
--- a/common_lib/schema_types.py
+++ b/common_lib/schema_types.py
@@ -1,7 +1,7 @@
 import graphene
+from django.conf import settings
 from django.db import models
 from graphene_django import DjangoObjectType
-from django.conf import settings
 
 from exercise.models import (
     Exercise,
@@ -33,8 +33,6 @@ from exercise_definition.models import (
 )
 from running_exercise.models import (
     ActionLog,
-    InjectSelection,
-    InjectOption,
     EmailThread,
     Email,
     ThreadParticipant,
@@ -229,16 +227,6 @@ class MilestoneStateType(DjangoObjectType):
         return [team.id for team in self.team_state.teams.all()]
 
 
-class InjectSelectionType(DjangoObjectType):
-    class Meta:
-        model = InjectSelection
-
-
-class InjectOptionType(DjangoObjectType):
-    class Meta:
-        model = InjectOption
-
-
 class EmailThreadType(DjangoObjectType):
     class Meta:
         model = EmailThread
diff --git a/common_lib/subscription_handler.py b/common_lib/subscription_handler.py
index 8daa21807bb0a1c3bc192c2fcea95ef5a753e9a6..7b40692acdaf53944681cda6a9a0bb04eda65e29 100644
--- a/common_lib/subscription_handler.py
+++ b/common_lib/subscription_handler.py
@@ -12,13 +12,11 @@ from exercise.subscription import ExercisesSubscription
 from running_exercise.models import (
     ActionLog,
     EmailThread,
-    InjectSelection,
 )
 from running_exercise.subscription import (
     ExerciseLoopRunningSubscription,
     ActionLogsSubscription,
     MilestonesSubscription,
-    InjectSelectionsSubscription,
     EmailThreadSubscription,
     AnalyticsMilestonesSubscription,
     AnalyticsActionLogsSubscription,
@@ -31,7 +29,6 @@ class SubscriptionHandler:
     _action_logs = ActionLogsSubscription
     _milestones = MilestonesSubscription
     _email_thread = EmailThreadSubscription
-    _inject_selection = InjectSelectionsSubscription
     _exercise_loop = ExerciseLoopRunningSubscription
     _exercises = ExercisesSubscription
     _analytics_milestones = AnalyticsMilestonesSubscription
@@ -113,14 +110,6 @@ class SubscriptionHandler:
                 group=str(participant.team_id),
             )
 
-    @classmethod
-    def broadcast_inject_selection(
-        cls, inject_selection: InjectSelection, team: Team
-    ):
-        cls._inject_selection.broadcast(
-            payload=inject_selection, group=str(team.id)
-        )
-
     @classmethod
     def broadcast_exercise_loop(cls, exercise: Exercise, running: bool):
         cls._exercise_loop.broadcast(payload=running, group=str(exercise.id))
diff --git a/definitions/CHANGELOG.md b/definitions/CHANGELOG.md
index fadf500b7d903334b822e5fe1da7e21e9de4b937..b596a1a633c9844809fcdf4178a6cb2dcd832587 100644
--- a/definitions/CHANGELOG.md
+++ b/definitions/CHANGELOG.md
@@ -1,3 +1,11 @@
+## 0.9.0
+Removed manual injects. #228
+All injects are now considered to be **automatic injects**.
+
+### injects.yml
+- remove field `auto`
+
+
 ## 0.8.0
 Add a new required concept called `learning objectives`. 
 This concept _must_ be included in all exercise definition. #170
diff --git a/definitions/README.md b/definitions/README.md
index 0c86039eb2922e06c6de97397fa944c07d604c56..116fb32b381ff45237e936f61241e5cc85795ca5 100644
--- a/definitions/README.md
+++ b/definitions/README.md
@@ -151,8 +151,6 @@ This file contains a list of injects.
 Each inject has the following fields:
 
 - **name**: _string, unique_ - name of the inject
-- **auto**: _bool_ - when true, this inject will be automatically sent to a team once the conditions are fulfilled.
-  When false, it is first sent to the instructor for selection.
 - **time**: _int, default=0_ - time since the beginning of the exercise in minutes,
  the inject will not be processed until this time has been reached
 - **delay**: _int, default=0_ - time in minutes, whenever this inject is about to be sent,
diff --git a/definitions/base_definition/config.yml b/definitions/base_definition/config.yml
index b218b0ff7815a7cbd499bd3785f22ce1e31d42db..7f080d02430c271f258a8d81b52fefe4a9d2024e 100644
--- a/definitions/base_definition/config.yml
+++ b/definitions/base_definition/config.yml
@@ -1,3 +1,3 @@
 exercise_duration: 60
 show_exercise_time: False
-version: 0.8.0
+version: 0.9.0
diff --git a/definitions/base_definition/injects.yml b/definitions/base_definition/injects.yml
index 28c941ba6ea56d476e60606a6617bc0e58857ad2..58827345621cfe58b1d041b15461b82f2d8e38a9 100644
--- a/definitions/base_definition/injects.yml
+++ b/definitions/base_definition/injects.yml
@@ -1,5 +1,4 @@
 - name: First Inject
-  auto: True
   organization: Org 1
   alternatives:
     - name: First inject
@@ -7,43 +6,8 @@
       content: { content: first inject which activates first_inject milestone }
       overlay: { duration: 1 }
 
-- name: First inject selection
-  auto: False
-  organization: Org 2
-  alternatives:
-    - name: First inject
-      control: { activate_milestone: inject_selection }
-      content:
-        content: |
-          This is the first inject.
-          NOTE TO INSTR
-          It is multiline and contains a file.
-        file_name: file1.txt
-
-    - name: Second inject
-      content:
-        content: |
-          This is the second inject.
-          NOTE TO INSTR 2
-          It is multiline and contains a file.
-        file_name: file1.txt
-    - name: Markdown inject
-      content: { content_path: simple.md }
-
-- name: Final inject selection
-  auto: False
-  alternatives:
-    - name: Evaluation great
-      control: { activate_milestone: evaluation_great }
-      content: { content: Good job, you finished the exercise. }
-
-    - name: Evaluation bad
-      control: { activate_milestone: evaluation_bad }
-      content: { content: You finished the exercise in a wrong way. }
-
 - name: Markdown lists showcase inject
   organization: Org 2
-  auto: True
   time: 1
   alternatives:
     - name: Auto markdown inject with lists
@@ -51,7 +15,6 @@
 
 - name: Markdown links showcase inject
   organization: Org 2
-  auto: True
   time: 2
   alternatives:
     - name: Auto markdown inject with links
@@ -59,7 +22,6 @@
 
 - name: Markdown text formatting showcase inject
   organization: Org 2
-  auto: True
   time: 3
   alternatives:
     - name: Auto markdown inject with text formatting
@@ -67,7 +29,6 @@
 
 - name: Delayed first inject
   organization: Org 1
-  auto: True
   delay: 1
   alternatives:
     - name: Delayed first inject
@@ -75,14 +36,12 @@
 
 
 - name: Timed inject
-  auto: True
   time: 3
   alternatives:
     - name: Timed inject
       content: { content: This is a timed inject which should arrive after 3 minutes. }
 
 - name: Conditional inject
-  auto: True
   time: 5
   alternatives:
     - name: 1 Inject
@@ -98,7 +57,6 @@
       control: { milestone_condition: evaluation_great }
 
 - name: Auto timed inject depends on website_traffic_blocked milestone
-  auto: True
   time: 6
   alternatives:
     - name: Inject option when not website_traffic_blocked
@@ -110,7 +68,6 @@
       content: { content: Website was blocked., file_name: website-root.jpg }
 
 - name: Timed inject when website visited but not blocked sending zip
-  auto: True
   organization: Org 1
   time: 10
   alternatives:
diff --git a/definitions/emails_definition/config.yml b/definitions/emails_definition/config.yml
index e7bd76d1c6394524de9f7fac82c0466d5c1aad64..3ce1d7f550a291e5beec0e3c2d69d0d73d920873 100644
--- a/definitions/emails_definition/config.yml
+++ b/definitions/emails_definition/config.yml
@@ -1,4 +1,4 @@
 exercise_duration: 60
 email_between_teams: True
 show_exercise_time: False
-version: 0.8.0
+version: 0.9.0
diff --git a/definitions/emails_definition/injects/after-3-min.yml b/definitions/emails_definition/injects/after-3-min.yml
index c96918f8ba047ba7369ab66e31e0d71b6a780030..eef65efe5752b198fa8e2aa596e0b01eddc28d9e 100644
--- a/definitions/emails_definition/injects/after-3-min.yml
+++ b/definitions/emails_definition/injects/after-3-min.yml
@@ -1,5 +1,4 @@
 - name: Timed inject
-  auto: True
   time: 3
   alternatives:
     - name: Timed inject
@@ -7,7 +6,6 @@
 
 
 - name: Auto timed inject depends on website_traffic_blocked milestone
-  auto: True
   time: 6
   type: email
   alternatives:
@@ -24,7 +22,6 @@
       content: { content: Website was blocked., file_name: website-root.jpg }
 
 - name: Timed inject when website visited but not blocked sending zip
-  auto: True
   time: 10
   type: email
   alternatives:
diff --git a/definitions/emails_definition/injects/before-3-min.yml b/definitions/emails_definition/injects/before-3-min.yml
index ebf2f9f56e95481c5fc6e802647f265a94607c14..5ed4d4a42e0e66ef826f3f32c086881d9d7751fe 100644
--- a/definitions/emails_definition/injects/before-3-min.yml
+++ b/definitions/emails_definition/injects/before-3-min.yml
@@ -1,36 +1,11 @@
 - name: First Inject
-  auto: True
   organization: Org 1
   alternatives:
     - name: First inject
       control: { activate_milestone: first_inject }
       content: { content: first inject which activates first_inject milestone }
 
-- name: First inject selection
-  auto: False
-  organization: Org 2
-  alternatives:
-    - name: First inject
-      control: { activate_milestone: inject_selection }
-      content:
-        content: |
-          This is the first inject.
-          NOTE TO INSTR
-          It is multiline and contains a file.
-        file_name: file1.txt
-
-    - name: Second inject
-      content:
-        content: |
-          This is the second inject.
-          NOTE TO INSTR 2
-          It is multiline and contains a file.
-        file_name: file1.txt
-    - name: Markdown inject
-      content: { content_path: simple.md }
-
 - name: Introductory inject email
-  auto: True
   type: email
   alternatives:
     - name: Introductory inject email
@@ -45,7 +20,6 @@
       overlay: { duration: 1 }
 
 - name: Repeated email
-  auto: True
   type: email
   alternatives:
     - name: Repeated email
@@ -56,14 +30,12 @@
 
 - name: Delayed first inject
   organization: Org 1
-  auto: True
   delay: 1
   alternatives:
     - name: Delayed first inject
       content: { content: This is the first delayed inject. }
 
 - name: Following email inject
-  auto: True
   time: 2
   type: email
   alternatives:
@@ -71,4 +43,3 @@
       sender: introductoryaddress@mail.ex
       subject: Introductory email thread
       content: { content: This is the second auto email inject in the thread. }
-
diff --git a/definitions/roles_definition/config.yml b/definitions/roles_definition/config.yml
index e3ba5f2370bae60a1b3df96a0ed48c1f23caee11..b9344056ebbadf50fb0285e79d5b6db6f950f453 100644
--- a/definitions/roles_definition/config.yml
+++ b/definitions/roles_definition/config.yml
@@ -1,4 +1,4 @@
 exercise_duration: 60
 show_exercise_time: False
 enable_roles: True
-version: 0.8.0
+version: 0.9.0
diff --git a/definitions/roles_definition/injects.yml b/definitions/roles_definition/injects.yml
index b03ecb54838ce96fd8c7f27c881c2ffc6ef78910..8b2e023b04e1d0758e4352f8fc3fe625f7dfd215 100644
--- a/definitions/roles_definition/injects.yml
+++ b/definitions/roles_definition/injects.yml
@@ -1,35 +1,12 @@
 - name: First Inject
-  auto: True
   organization: Org 1
   alternatives:
     - name: First inject
       control: { activate_milestone: first_inject }
       content: { content: first inject which activates first_inject milestone }
 
-- name: First inject selection
-  auto: False
-  organization: Org 2
-  alternatives:
-    - name: First inject
-      control: { activate_milestone: inject_selection }
-      content:
-        content: |
-          This is the first inject.
-          NOTE TO INSTR
-          It is multiline and contains a file.
-        file_name: file1.txt
-
-    - name: Second inject
-      content:
-        content: |
-          This is the second inject.
-          NOTE TO INSTR 2
-          It is multiline and contains a file.
-        file_name: file1.txt
-
 - name: Delayed first inject
   organization: Org 1
-  auto: True
   delay: 1
   alternatives:
     - name: Delayed first inject
@@ -37,7 +14,6 @@
 
 
 - name: Timed inject
-  auto: True
   time: 3
   alternatives:
     - name: Timed inject
@@ -45,7 +21,6 @@
 
 
 - name: Auto timed inject depends on website_traffic_blocked milestone
-  auto: True
   time: 6
   alternatives:
     - name: Inject option when not website_traffic_blocked
@@ -57,7 +32,6 @@
       content: { content: Website was blocked., file_name: website-root.jpg }
 
 - name: Timed inject when website visited but not blocked sending zip
-  auto: True
   organization: Org 1
   time: 10
   alternatives:
@@ -70,7 +44,6 @@
         file_name: two_files.zip
 
 - name: Role dependent inject
-  auto: True
   alternatives:
     - name: Inject for role_1
       content: { content: Hello role_1, file_name: file1.txt }
@@ -85,21 +58,3 @@
       content: { content: Hello role_3 }
       control: { roles: role_3 }
       overlay: { duration: 1 }
-
-- name: Role dependent inject selection
-  auto: False
-  alternatives:
-    - name: Inject for role_1
-      content: { content: Selection for role_1, file_name: file1.txt }
-      control: { roles: role_1 }
-
-    - name: Inject for role_2
-      content: { content: Selection for role_2, file_name: file2.txt }
-      control: { roles: role_2 }
-
-    - name: Inject for role_3
-      content: { content: Selection for role_3 }
-      control: { roles: role_3 }
-
-    - name: Inject for all roles
-      content: { content: Selection for all roles }
diff --git a/exercise/migrations/0006_alter_teaminjectstate_status.py b/exercise/migrations/0006_alter_teaminjectstate_status.py
new file mode 100644
index 0000000000000000000000000000000000000000..74c46f4021acd283c7e59cba3cb41a44967f2537
--- /dev/null
+++ b/exercise/migrations/0006_alter_teaminjectstate_status.py
@@ -0,0 +1,18 @@
+# Generated by Django 3.2.22 on 2024-07-10 15:56
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('exercise', '0005_auto_20240625_1241'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='teaminjectstate',
+            name='status',
+            field=models.IntegerField(choices=[(0, 'Unsent'), (2, 'Delayed'), (4, 'Sent')], default=0),
+        ),
+    ]
diff --git a/exercise/models.py b/exercise/models.py
index db1fc8e3c82038104ed7cdb61df5a3de2f2cbc95..5e0e5018c8427d61a90dd6f298585b83a0b51afa 100644
--- a/exercise/models.py
+++ b/exercise/models.py
@@ -137,8 +137,7 @@ class TeamInjectState(models.Model):
     class Status(models.IntegerChoices):
         UNSENT = 0
         DELAYED = 2
-        SELECTION = 4
-        SENT = 6
+        SENT = 4
 
     team = models.ForeignKey(
         Team, on_delete=models.CASCADE, related_name="inject_states"
diff --git a/exercise/schema/query.py b/exercise/schema/query.py
index 64bc2b78c46248f4ffac8bfc76deed36ca8af528..31d36ce8f8c52c99ebd61989ad7a45c0fd0bfa22 100644
--- a/exercise/schema/query.py
+++ b/exercise/schema/query.py
@@ -1,8 +1,9 @@
 from typing import Optional, List
-import graphene
 
+import graphene
 from django.conf import settings
 
+from aai.utils import protected, extra_protected, Check
 from common_lib.schema_types import (
     ExerciseType,
     DefinitionType,
@@ -21,7 +22,6 @@ from exercise_definition.models import (
     Channel,
 )
 from user.models import User
-from aai.utils import protected, extra_protected, Check
 
 
 class Query(graphene.ObjectType):
@@ -58,10 +58,10 @@ class Query(graphene.ObjectType):
         definition_id=graphene.ID(required=True),
         description="Retrieve a specific definition",
     )
-    auto_injects = graphene.List(
+    injects = graphene.List(
         DefinitionInjectType,
         exercise_id=graphene.ID(required=True),
-        description="Retrieve all auto inject categories",
+        description="Retrieve all automatic injects",
     )
 
     milestones = graphene.List(
@@ -156,15 +156,8 @@ class Query(graphene.ObjectType):
 
     @protected(User.AuthGroup.INSTRUCTOR)
     @extra_protected(Check.EXERCISE_ID)
-    def resolve_auto_injects(self, info, exercise_id: str) -> List[Inject]:
-        exercise = get_model(
-            Exercise,
-            id=int(exercise_id),
-        )
-
-        return Inject.objects.filter(
-            definition_id=exercise.definition.id, auto=True
-        )
+    def resolve_injects(self, info, exercise_id: str) -> List[Inject]:
+        return Inject.objects.filter(definition__exercises__in=[exercise_id])
 
     @protected(User.AuthGroup.INSTRUCTOR)
     @extra_protected(Check.EXERCISE_ID)
diff --git a/exercise_definition/lib/definition_uploader.py b/exercise_definition/lib/definition_uploader.py
index 6e818c7ac386aff297e04adc0430d69bfd50a399..1293eb066169dbf39d03a9ec964feb9906a721ce 100644
--- a/exercise_definition/lib/definition_uploader.py
+++ b/exercise_definition/lib/definition_uploader.py
@@ -100,7 +100,6 @@ def _convert_to_inject(
 ) -> Inject:
     return Inject.objects.create(
         name=yaml_inject.name,
-        auto=yaml_inject.auto,
         time=yaml_inject.time,
         delay=yaml_inject.delay,
         organization=yaml_inject.organization,
diff --git a/exercise_definition/migrations/0005_remove_inject_auto.py b/exercise_definition/migrations/0005_remove_inject_auto.py
new file mode 100644
index 0000000000000000000000000000000000000000..bdf2abdf873bb470af0202db35f9e6b9620c2477
--- /dev/null
+++ b/exercise_definition/migrations/0005_remove_inject_auto.py
@@ -0,0 +1,17 @@
+# Generated by Django 3.2.22 on 2024-07-10 15:37
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('exercise_definition', '0004_auto_20240625_1239'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='inject',
+            name='auto',
+        ),
+    ]
diff --git a/exercise_definition/models/models.py b/exercise_definition/models/models.py
index 915247a0d7240d49f53b379fc815b0d03df3707d..b1bfaea5263fab995005759e0cc5a3c8293f2f59 100644
--- a/exercise_definition/models/models.py
+++ b/exercise_definition/models/models.py
@@ -266,7 +266,6 @@ Alternative = Union["InfoAlternative", "EmailAlternative"]
 
 class Inject(models.Model):
     name = models.TextField()
-    auto = models.BooleanField()
     time = models.IntegerField()
     delay = models.IntegerField()
     organization = models.TextField()
diff --git a/exercise_definition/models/yaml_models.py b/exercise_definition/models/yaml_models.py
index 7f6c291efb27499cd5a03ad781c5382ec41e5fa8..5a72debce99e164e2bcee09f6f370a10b44e1ec9 100644
--- a/exercise_definition/models/yaml_models.py
+++ b/exercise_definition/models/yaml_models.py
@@ -178,7 +178,6 @@ INJECT_TYPE_MAPPING: Dict[str, Type[Yamlizable]] = {
 
 class YamlInject(Object):
     name = Attribute(type=str)
-    auto = Attribute(type=bool)
     time = Attribute(type=int, default=0)
     delay = Attribute(type=int, default=0)
     organization = Attribute(type=str, default="")
diff --git a/exercise_definition/serializers.py b/exercise_definition/serializers.py
index d2f47182bfb5315cfd2e87348235d3de7d1e479a..13ee6b136237e9a2c2db683c11af7a0617cd51be 100644
--- a/exercise_definition/serializers.py
+++ b/exercise_definition/serializers.py
@@ -110,7 +110,6 @@ class InjectSerializer(ModelSerializer):
         fields = [
             "inject_id",
             "name",
-            "auto",
             "time",
             "delay",
             "organization",
diff --git a/exercise_definition/tests/validation/inject_validation_test.py b/exercise_definition/tests/validation/inject_validation_test.py
index 65e7e67f48d0fa6aca45d42f49d71039ce928f87..966387649ae981f52c23020d5758319edd64091a 100644
--- a/exercise_definition/tests/validation/inject_validation_test.py
+++ b/exercise_definition/tests/validation/inject_validation_test.py
@@ -9,7 +9,6 @@ class InjectValidationTestCase(TestCase):
         inject: YamlInject = YamlInject.load(
             """
         name: inject name
-        auto: True
         type: email
         alternatives:
           - name: some name
@@ -27,7 +26,6 @@ class InjectValidationTestCase(TestCase):
         inject: YamlInject = YamlInject.load(
             """
         name: inject name
-        auto: True
         type: email
         alternatives:
           - name: some name
diff --git a/running_exercise/lib/exercise_updater.py b/running_exercise/lib/exercise_updater.py
index 69c61f5a98cc663b641f655bbf3b3a49cd1d3335..e1e714bf22e5657653723baac974cafde4c8da29 100644
--- a/running_exercise/lib/exercise_updater.py
+++ b/running_exercise/lib/exercise_updater.py
@@ -26,8 +26,6 @@ from running_exercise.lib.milestone_handler import (
 )
 from running_exercise.lib.utils import create_action_log, check_control
 from running_exercise.models import (
-    InjectOption,
-    InjectSelection,
     InjectDetails,
     Email,
     ActionLog,
@@ -42,43 +40,6 @@ def _check_conditions(inject_state: TeamInjectState) -> List[Alternative]:
     ]
 
 
-def _convert_to_inject_option(alternative: Alternative) -> InjectOption:
-    if isinstance(alternative, EmailAlternative):
-        return InjectOption(
-            name=alternative.name,
-            sender=alternative.sender,
-            control=alternative.control,
-            content=alternative.content,
-        )
-
-    # This MUST go
-    return InjectOption(
-        name=alternative.name,
-        control=alternative.control,
-        content=alternative.content,
-    )
-
-
-# TODO: Inject selections will be reworked later
-def _send_selection(inject_state: TeamInjectState, injects: List[Alternative]):
-    options = [_convert_to_inject_option(inject) for inject in injects]
-
-    selection = InjectSelection.objects.create(
-        team=inject_state.team,
-        name=inject_state.inject.name,
-        timestamp=timezone.now(),
-        team_inject=inject_state,
-    )
-
-    for option in options:
-        option.inject_selection = selection
-        option.save()
-
-    inject_state.status = TeamInjectState.Status.SELECTION
-    inject_state.save()
-    SubscriptionHandler.broadcast_inject_selection(selection, inject_state.team)
-
-
 def _send_inject(inject_state: TeamInjectState, channels: Dict[str, Channel]):
     """
     Send the selected inject to the team and mark the category as sent.
@@ -142,10 +103,6 @@ def _check_inject(inject_state: TeamInjectState, seconds: int) -> bool:
     if len(sendable_alternatives) == 0:
         return False
 
-    if not inject_state.inject.auto:
-        _send_selection(inject_state, sendable_alternatives)
-        return False
-
     # only one inject can be sent from a category, priority is determined by the name
     # the injects in the db are already ordered by name, therefore the first inject
     # has the priority
@@ -193,7 +150,7 @@ class ExerciseUpdater:
         injects = TeamInjectState.objects.filter(
             team__exercise=self.exercise,
             inject__time__lte=exercise_minutes,
-            status__lt=TeamInjectState.Status.SELECTION,
+            status__lt=TeamInjectState.Status.SENT,
         ).prefetch_related("inject", "team")
 
         for inject in injects:  # type: TeamInjectState
diff --git a/running_exercise/lib/inject_selector.py b/running_exercise/lib/inject_selector.py
deleted file mode 100644
index d1df40e574a3262d8fb206ea37a2be7c4c724022..0000000000000000000000000000000000000000
--- a/running_exercise/lib/inject_selector.py
+++ /dev/null
@@ -1,118 +0,0 @@
-from typing import Optional
-
-from markdown import markdown
-
-from common_lib.exceptions import RunningExerciseOperationException
-from common_lib.utils import get_model
-from exercise.models import Team, EmailParticipant
-from exercise_definition.models import (
-    FileInfo,
-    Content,
-    Control,
-    Channel,
-    InjectTypes,
-)
-from running_exercise.graphql_inputs import (
-    SelectTeamInjectInput,
-)
-from running_exercise.lib.email_client import EmailClient, send_email
-from running_exercise.lib.milestone_handler import update_milestones
-from running_exercise.lib.utils import create_action_log
-from running_exercise.models import (
-    InjectSelection,
-    InjectDetails,
-    CustomInjectDetails,
-    Email,
-)
-from user.models import User
-
-CUSTOM_INJECT_SELECTION_ID = "-1"
-
-
-class InjectSelector:
-    @staticmethod
-    def select_inject(
-        select_team_inject_input: SelectTeamInjectInput,
-        user: Optional[User] = None,
-    ):
-        team = get_model(Team, id=select_team_inject_input.team_id)
-        if select_team_inject_input.file_id != "":
-            file_info = get_model(FileInfo, id=select_team_inject_input.file_id)
-        else:
-            file_info = None
-
-        selection: Optional[InjectSelection] = None
-        if select_team_inject_input.selection_id != CUSTOM_INJECT_SELECTION_ID:
-            selection = get_model(
-                InjectSelection, id=int(select_team_inject_input.selection_id)
-            )
-            if selection.team_id != team.id:
-                raise RunningExerciseOperationException(
-                    "Invalid selection attempt, team has no inject selection "
-                    "with this id"
-                )
-
-            InjectSelection.objects.filter(
-                pk=select_team_inject_input.selection_id
-            ).delete()
-
-        update_milestones(
-            team,
-            Control(
-                activate_milestone=select_team_inject_input.activate_milestone,
-                deactivate_milestone=select_team_inject_input.deactivate_milestone,
-            ),
-        )
-
-        # unfortunately, there is currently no good way to tell which inject option this came from,
-        # if any, which prevents us from using the pre-rendered markdown,
-        # furthermore, we do not know if the content has been modified
-        # the easiest way to handle this is to consider all content to be modified,
-        # and pass it to the renderer, this MUST be reworked at some point in the future
-        content = Content.objects.create(
-            raw=select_team_inject_input.content,
-            rendered=markdown(select_team_inject_input.content),
-            file_info=file_info,
-        )
-        if select_team_inject_input.option_email:
-            sender = get_model(
-                EmailParticipant,
-                team.exercise.email_participants,
-                address=select_team_inject_input.sender,
-            )
-            thread = EmailClient.get_thread(
-                team,
-                select_team_inject_input.sender,
-                select_team_inject_input.subject,
-            )
-            channel = get_model(
-                Channel,
-                sender.exercise.definition.channels,
-                type=InjectTypes.EMAIL,
-            )
-            email = Email.objects.create(
-                thread=thread,
-                sender=sender,
-                content=content,
-            )
-
-            for _ in range(select_team_inject_input.repeat + 1):
-                send_email(email=email, channel=channel)
-        else:
-            channel = get_model(
-                Channel,
-                team.exercise.definition.channels,
-                type=InjectTypes.INFO,
-            )
-            if selection is not None:
-                details = InjectDetails.objects.create(
-                    inject=selection.team_inject.inject,
-                    content=content,
-                )
-            else:
-                details = CustomInjectDetails.objects.create(
-                    content=content,
-                    user=user,
-                )
-            for _ in range(select_team_inject_input.repeat + 1):
-                create_action_log(team, details, channel)
diff --git a/running_exercise/migrations/0006_auto_20240712_1028.py b/running_exercise/migrations/0006_auto_20240712_1028.py
new file mode 100644
index 0000000000000000000000000000000000000000..fa789154d675e755582d0a2a2e1773d2815ff4c2
--- /dev/null
+++ b/running_exercise/migrations/0006_auto_20240712_1028.py
@@ -0,0 +1,27 @@
+# Generated by Django 3.2.22 on 2024-07-12 10:28
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('running_exercise', '0005_custominjectdetails_overlay'),
+    ]
+
+    operations = [
+        migrations.RemoveField(
+            model_name='injectselection',
+            name='team',
+        ),
+        migrations.RemoveField(
+            model_name='injectselection',
+            name='team_inject',
+        ),
+        migrations.DeleteModel(
+            name='InjectOption',
+        ),
+        migrations.DeleteModel(
+            name='InjectSelection',
+        ),
+    ]
diff --git a/running_exercise/models.py b/running_exercise/models.py
index 5e7ad3b3f13197819cfc834df249182e902e94e4..095916f8fe34b8b29799e980935d949022da60ce 100644
--- a/running_exercise/models.py
+++ b/running_exercise/models.py
@@ -211,39 +211,6 @@ class ThreadParticipant(models.Model):
         default_permissions = ()
 
 
-class InjectSelection(models.Model):
-    name = models.TextField()
-    timestamp = models.DateTimeField(null=True, blank=True)
-    team = models.ForeignKey(
-        Team, on_delete=models.CASCADE, related_name="inject_selections"
-    )
-    team_inject = models.ForeignKey(
-        TeamInjectState, on_delete=models.CASCADE, related_name="selections"
-    )
-
-    class Meta:
-        ordering = ["id"]
-        default_permissions = ()
-
-
-class InjectOption(models.Model):
-    name = models.TextField()
-    sender = models.TextField(default="")
-    control = models.ForeignKey(
-        Control, on_delete=models.CASCADE, related_name="+"
-    )
-    content = models.ForeignKey(
-        Content, on_delete=models.CASCADE, related_name="+"
-    )
-    inject_selection = models.ForeignKey(
-        InjectSelection, on_delete=models.CASCADE, related_name="options"
-    )
-
-    class Meta:
-        ordering = ["id"]
-        default_permissions = ()
-
-
 class TeamFile(models.Model):
     team = models.ForeignKey(
         Team, on_delete=models.CASCADE, related_name="uploaded_files"
diff --git a/running_exercise/schema/mutation.py b/running_exercise/schema/mutation.py
index 7f3d6f9545ec402850ac4304bcf9bc73190a7266..eb86b1268c0aca6d54b35e72250d8bc4ba24b523 100644
--- a/running_exercise/schema/mutation.py
+++ b/running_exercise/schema/mutation.py
@@ -7,7 +7,6 @@ from aai.utils import protected, extra_protected, input_object_protected, Check
 from common_lib.logger import logger
 from common_lib.schema_types import ExerciseType, EmailThreadType
 from running_exercise.graphql_inputs import (
-    SelectTeamInjectInput,
     UseToolInput,
     SendEmailInput,
     QuestionnaireInput,
@@ -15,9 +14,6 @@ from running_exercise.graphql_inputs import (
 )
 from running_exercise.lib.email_client import EmailClient
 from running_exercise.lib.exercise_loop import ExerciseLoop
-from running_exercise.lib.inject_selector import (
-    InjectSelector,
-)
 from running_exercise.lib.instructor_action_handler import (
     InstructorActionHandler,
 )
@@ -47,25 +43,6 @@ class UseToolMutation(graphene.Mutation):
         return UseToolMutation(operation_done=True)
 
 
-class SelectTeamInjectOptionMutation(graphene.Mutation):
-    class Arguments:
-        select_team_inject_input = graphene.Argument(
-            SelectTeamInjectInput, required=True
-        )
-
-    operation_done = graphene.Boolean()
-
-    @classmethod
-    @protected(User.AuthGroup.INSTRUCTOR)
-    @input_object_protected("select_team_inject_input")
-    def mutate(
-        cls, root, info, select_team_inject_input: SelectTeamInjectInput
-    ) -> graphene.Mutation:
-        user = None if settings.NOAUTH else info.context.user
-        InjectSelector.select_inject(select_team_inject_input, user)
-        return SelectTeamInjectOptionMutation(operation_done=True)
-
-
 class CreateThreadMutation(graphene.Mutation):
     class Arguments:
         participant_addresses = graphene.List(
@@ -219,9 +196,6 @@ class Mutation(graphene.ObjectType):
     use_tool = UseToolMutation.Field(
         description="Mutation for performing a tool action"
     )
-    select_team_inject_option = SelectTeamInjectOptionMutation.Field(
-        description="Mutation for selecting an inject for a specific team"
-    )
     move_time = MoveExerciseTimeMutation.Field(
         description="Mutation for moving the in-exercise time by the specified amount of seconds"
     )
diff --git a/running_exercise/schema/query.py b/running_exercise/schema/query.py
index 503fb66e488e82b465521ceaca69395201125892..82efe25eb5cfe614c0edfeb907b4322181acfae8 100644
--- a/running_exercise/schema/query.py
+++ b/running_exercise/schema/query.py
@@ -9,7 +9,6 @@ from common_lib.exceptions import RunningExerciseOperationException
 from common_lib.schema_types import (
     ActionLogType,
     MilestoneStateType,
-    InjectSelectionType,
     EmailThreadType,
     TeamLearningObjectiveType,
     ToolType,
@@ -39,7 +38,7 @@ from running_exercise.lib.email_client import EmailClient
 from running_exercise.lib.exercise_loop import ExerciseLoop
 from running_exercise.lib.milestone_handler import get_milestone_states
 from running_exercise.lib.utils import get_running_exercise
-from running_exercise.models import ActionLog, InjectSelection, EmailThread
+from running_exercise.models import ActionLog, EmailThread
 
 
 class Query(graphene.ObjectType):
@@ -88,11 +87,6 @@ class Query(graphene.ObjectType):
         ),
         description="Retrieve all milestones for the specific team filtered by team visibility",
     )
-    team_inject_selections = graphene.List(
-        InjectSelectionType,
-        team_id=graphene.ID(required=True),
-        description="Retrieve all available inject selections for the specific team. Useful for the instructor view.",
-    )
     email_contacts = graphene.List(
         EmailParticipantType,
         visible_only=graphene.Boolean(
@@ -266,13 +260,6 @@ class Query(graphene.ObjectType):
     ) -> List[MilestoneState]:
         return get_milestone_states(int(team_id), visible_only)
 
-    @protected(User.AuthGroup.INSTRUCTOR)
-    @extra_protected(Check.TEAM_ID)
-    def resolve_team_inject_selections(
-        self, info, team_id: str
-    ) -> QuerySet[InjectSelection]:
-        return InjectSelection.objects.filter(team_id=team_id)
-
     @protected(User.AuthGroup.TRAINEE)
     @extra_protected(Check.VISIBLE_ONLY)
     def resolve_email_contacts(
diff --git a/running_exercise/subscription.py b/running_exercise/subscription.py
index 5e4a93badd9b18b9373f2345c589d75206312662..68f1078dd62b2e7edd8f7a9992fb4f59007b0089 100644
--- a/running_exercise/subscription.py
+++ b/running_exercise/subscription.py
@@ -6,7 +6,6 @@ from aai.utils import protected, extra_protected, Check
 from common_lib.schema_types import (
     ActionLogType,
     MilestoneStateType,
-    InjectSelectionType,
     EmailThreadType,
     TeamQuestionnaireStateType,
 )
@@ -81,25 +80,6 @@ class MilestonesSubscription(channels_graphql_ws.Subscription):
         return MilestonesSubscription(milestones=payload)
 
 
-class InjectSelectionsSubscription(channels_graphql_ws.Subscription):
-    notification_queue_limit = NOTIFICATION_QUEUE_LIMIT
-    inject_selection = graphene.Field(InjectSelectionType)
-
-    class Arguments:
-        team_id = graphene.ID()
-
-    @staticmethod
-    @protected(User.AuthGroup.INSTRUCTOR)
-    @extra_protected(Check.TEAM_ID)
-    def subscribe(root, info, team_id: str):
-        get_model(Team, id=int(team_id))
-        return [team_id]
-
-    @staticmethod
-    def publish(payload, info, team_id: str):
-        return InjectSelectionsSubscription(inject_selection=payload)
-
-
 class EmailThreadSubscription(channels_graphql_ws.Subscription):
     notification_queue_limit = NOTIFICATION_QUEUE_LIMIT
     email_thread = graphene.Field(EmailThreadType)
@@ -206,9 +186,6 @@ class Subscription(graphene.ObjectType):
     milestones = MilestonesSubscription.Field(
         description="Subscription notifies about changes in milestone states"
     )
-    inject_selections = InjectSelectionsSubscription.Field(
-        description="Subscription notifies about new inject selections available for the specific team"
-    )
     email_threads = EmailThreadSubscription.Field(
         description="Subscription notifies about new threads and new emails for the specific team"
     )
diff --git a/running_exercise/tests/exercise_updater_tests.py b/running_exercise/tests/exercise_updater_tests.py
index 0ed533f14dc232dcde618581115badc1afe24d98..5c631f3b35f66cb00302e856df793a89026a8762 100644
--- a/running_exercise/tests/exercise_updater_tests.py
+++ b/running_exercise/tests/exercise_updater_tests.py
@@ -72,25 +72,6 @@ class ExerciseUpdaterTestCase(TestCase):
         )
         self.assertIsNotNone(sendable_alternatives[0].overlay)
 
-        inject_state = team.inject_states.get(
-            inject__name="First inject selection"
-        )
-        sendable_alternatives = _check_conditions(inject_state)
-
-        self.assertEqual(len(sendable_alternatives), 3)
-
-        for alternative in sendable_alternatives:
-            if alternative.name == "Markdown inject":
-                continue
-            if alternative.name == "First inject":
-                self.assertEqual(
-                    alternative.control.activate_milestone, "inject_selection"
-                )
-
-            self.assertEqual(
-                alternative.content.file_info.file_name, "file1.txt"
-            )
-
         inject_state = team.inject_states.get(
             inject__name="Auto timed inject depends on website_traffic_blocked milestone"
         )
@@ -142,16 +123,6 @@ class ExerciseUpdaterTestCase(TestCase):
         self.assertEqual(sendable_alternatives[0].name, "Inject for role_1")
         self.assertIsNotNone(sendable_alternatives[0].overlay)
 
-        inject_state = role_1.inject_states.get(
-            inject__name="Role dependent inject selection"
-        )
-        sendable_alternatives = _check_conditions(inject_state)
-        self.assertEqual(len(sendable_alternatives), 2)
-        for alternative in sendable_alternatives:
-            self.assertIn(
-                alternative.name, ["Inject for role_1", "Inject for all roles"]
-            )
-
         role_2 = self.roles_exercise.teams.get(role="role_2")
         inject_state = role_2.inject_states.get(
             inject__name="Role dependent inject"
@@ -161,31 +132,9 @@ class ExerciseUpdaterTestCase(TestCase):
         self.assertEqual(sendable_alternatives[0].name, "Inject for role_2")
         self.assertIsNone(sendable_alternatives[0].overlay)
 
-        inject_state = role_2.inject_states.get(
-            inject__name="Role dependent inject selection"
-        )
-        sendable_alternatives = _check_conditions(inject_state)
-        self.assertEqual(len(sendable_alternatives), 2)
-        for alternative in sendable_alternatives:
-            self.assertIn(
-                alternative.name, ["Inject for role_2", "Inject for all roles"]
-            )
-
     def test_check_category_base(self):
         team: Team = self.base_exercise.teams.first()
 
-        inject_state = team.inject_states.get(
-            inject__name="First inject selection"
-        )
-
-        self.assertFalse(
-            _check_inject(inject_state, 0),
-            msg="Inject should be ready to be sent",
-        )
-
-        self.assertEqual(inject_state.status, TeamInjectState.Status.SELECTION)
-        self.assertEqual(team.inject_selections.count(), 1)
-
         inject_state = team.inject_states.get(inject__name="Conditional inject")
         website_visited = self.base_definition.milestones.get(
             name="website_visited"