diff --git a/CHANGELOG.md b/CHANGELOG.md
index e644fddc66f5e9fc311451d867eccb4ed1cd17d4..90de22193fb04520cd56769993de421ee5e0f1cf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,4 @@
+2024-05-07 - add the option to add not team-visible addresses to the recipients list
 2024-05-07 - add exercise name, rework exercise panel add dialogs
 2024-05-07 - add learning objectives page to the instructor view
 2024-05-07 - change the tab icon to the INJECT logo
diff --git a/backend b/backend
index caf6b1c1038b43f45124e4a9220e63d822a8e900..b0d99e75be6486619ae5abddcfc347c79c72f54a 160000
--- a/backend
+++ b/backend
@@ -1 +1 @@
-Subproject commit caf6b1c1038b43f45124e4a9220e63d822a8e900
+Subproject commit b0d99e75be6486619ae5abddcfc347c79c72f54a
diff --git a/codegen/gql/queries/ValidateEmailAddress.graphql b/codegen/gql/queries/ValidateEmailAddress.graphql
new file mode 100644
index 0000000000000000000000000000000000000000..2ef838079f31ff131544a20ce352e7c46cdd7edb
--- /dev/null
+++ b/codegen/gql/queries/ValidateEmailAddress.graphql
@@ -0,0 +1,3 @@
+query ValidateEmailAddress($exerciseId: ID!, $address: String!) {
+  validateEmailAddress(exerciseId: $exerciseId, address: $address)
+}
diff --git a/frontend/src/email/EmailContactSelector/index.tsx b/frontend/src/email/EmailContactSelector/index.tsx
index 6f2d7e92ddaaa4c27c278a73a47241b244b08e22..430e86bb34dc29b3f981fd079cd8f8d050c1a191 100644
--- a/frontend/src/email/EmailContactSelector/index.tsx
+++ b/frontend/src/email/EmailContactSelector/index.tsx
@@ -2,7 +2,9 @@ import { MenuItem, Tooltip } from '@blueprintjs/core'
 import type { ItemRenderer } from '@blueprintjs/select'
 import { MultiSelect } from '@blueprintjs/select'
 import type { EmailParticipant } from '@inject/graphql/fragments/EmailParticipant.generated'
-import type { Dispatch, FC, SetStateAction } from 'react'
+import { useValidateEmailAddressLazyQuery } from '@inject/graphql/queries/ValidateEmailAddress.generated'
+import { useNotifyContext } from '@inject/shared/notification/contexts/NotifyContext'
+import type { Dispatch, FC, MouseEventHandler, SetStateAction } from 'react'
 import { memo, useCallback, useMemo } from 'react'
 import type { ExtendedItemRenderer } from '../typing'
 
@@ -12,6 +14,7 @@ interface EmailContactSelectorProps {
   selectedContacts: string[]
   setSelectedContacts: Dispatch<SetStateAction<string[]>>
   inInstructor: boolean
+  exerciseId: string
 }
 
 const EmailContactSelector: FC<EmailContactSelectorProps> = ({
@@ -20,12 +23,17 @@ const EmailContactSelector: FC<EmailContactSelectorProps> = ({
   senderAddress,
   setSelectedContacts,
   inInstructor,
+  exerciseId,
 }) => {
   const suggestedItems = useMemo(
     () => emailContacts.map(x => x?.address || '') || [],
     [emailContacts]
   )
 
+  const [validateEmailAddress] = useValidateEmailAddressLazyQuery()
+
+  const { notify } = useNotifyContext()
+
   const itemRenderer: ExtendedItemRenderer<string> = useCallback(
     (i, { handleClick, handleFocus, modifiers, hasTooltip }) => (
       <MenuItem
@@ -66,20 +74,55 @@ const EmailContactSelector: FC<EmailContactSelectorProps> = ({
     [selectedContacts, senderAddress]
   )
   const onItemSelect = useCallback(
-    (i: string) =>
+    async (i: string) => {
+      const { data: validateData } = await validateEmailAddress({
+        variables: {
+          exerciseId,
+          address: i,
+        },
+      })
+      if (!validateData?.validateEmailAddress) {
+        notify('Invalid email address', { intent: 'danger' })
+        return
+      }
+
       setSelectedContacts(prev => {
         if (prev.includes(i)) {
           return prev.filter(x => x !== i)
         }
         return [...prev, i]
-      }),
-    [setSelectedContacts]
+      })
+    },
+    [exerciseId, notify, setSelectedContacts, validateEmailAddress]
   )
   const onRemove = useCallback(
     (i: string) => setSelectedContacts(prev => prev.filter(x => x !== i)),
     [setSelectedContacts]
   )
 
+  const createNewItemFromQuery: (query: string) => string | string[] =
+    useCallback((query: string) => query, [])
+  const createNewItemRenderer: (
+    query: string,
+    active: boolean,
+    handleClick: MouseEventHandler<HTMLElement>
+  ) => undefined | JSX.Element = useCallback(
+    (
+      query: string,
+      active: boolean,
+      handleClick: MouseEventHandler<HTMLElement>
+    ) => (
+      <MenuItem
+        active={active}
+        onClick={handleClick}
+        roleStructure='listoption'
+        shouldDismissPopover={false}
+        text={query}
+      />
+    ),
+    []
+  )
+
   return (
     <MultiSelect<string>
       placeholder='Recipients'
@@ -98,6 +141,8 @@ const EmailContactSelector: FC<EmailContactSelectorProps> = ({
       popoverContentProps={{
         style: { maxHeight: '50vh', overflowY: 'auto', overflowX: 'hidden' },
       }}
+      createNewItemFromQuery={createNewItemFromQuery}
+      createNewItemRenderer={createNewItemRenderer}
     />
   )
 }
diff --git a/frontend/src/email/EmailForm/TraineeEmailForm.tsx b/frontend/src/email/EmailForm/TraineeEmailForm.tsx
index fddea42ed4125ca80328ad2eb8bf01c8f35a8c31..757f4ccf6d7da01c0ab9f3ca3034cc7bbba10f5e 100644
--- a/frontend/src/email/EmailForm/TraineeEmailForm.tsx
+++ b/frontend/src/email/EmailForm/TraineeEmailForm.tsx
@@ -110,6 +110,7 @@ const TraineeEmailForm: FC<TraineeEmailFormProps> = ({
             })}
         contacts={traineeList}
         senderAddress={teamAddress}
+        exerciseId={exerciseId}
       />
       <Divider style={{ margin: '0.5rem 0' }} />
 
diff --git a/frontend/src/email/EmailForm/modules/HeaderArea.tsx b/frontend/src/email/EmailForm/modules/HeaderArea.tsx
index cf3be622b850d13b53b5f69a1e1c1ef6899a4b6e..369735ba78c2844792fbe33426b86db4991647a2 100644
--- a/frontend/src/email/EmailForm/modules/HeaderArea.tsx
+++ b/frontend/src/email/EmailForm/modules/HeaderArea.tsx
@@ -54,7 +54,6 @@ type HeaderAreaProps = (
         template: EmailTemplate | undefined
         setTemplate: Dispatch<SetStateAction<EmailTemplate | undefined>>
         teamId: string
-        exerciseId: string
       }
     | {
         // trainee
@@ -67,11 +66,11 @@ type HeaderAreaProps = (
         template?: undefined
         setTemplate?: undefined
         teamId?: undefined
-        exerciseId?: undefined
       }
   ) & {
     senderAddress: string
     contacts: EmailParticipant[]
+    exerciseId: string
   }
 
 const HeaderArea: FC<HeaderAreaProps> = ({
@@ -136,6 +135,7 @@ const HeaderArea: FC<HeaderAreaProps> = ({
           senderAddress={senderAddress}
           setSelectedContacts={setSelectedContacts}
           inInstructor={senderList !== undefined}
+          exerciseId={exerciseId}
         />
       )}
 
diff --git a/graphql/client/apollo-helpers.ts b/graphql/client/apollo-helpers.ts
index eae3a4192ac52598b5d6a348b91cf551329f921d..76fc773516248c0b22ef948ea845824818db08cb 100644
--- a/graphql/client/apollo-helpers.ts
+++ b/graphql/client/apollo-helpers.ts
@@ -421,7 +421,7 @@ export type PasswordChangeKeySpecifier = ('passwordChanged' | PasswordChangeKeyS
 export type PasswordChangeFieldPolicy = {
 	passwordChanged?: FieldPolicy<any> | FieldReadFunction<any>
 };
-export type QueryKeySpecifier = ('actionLog' | 'analyticsActionLogs' | 'analyticsEmailThreads' | 'analyticsMilestones' | 'autoInjects' | 'channel' | 'definition' | 'definitions' | 'emailAddresses' | 'emailContact' | 'emailContacts' | 'emailTemplates' | 'emailThread' | 'emailThreads' | 'exerciseChannels' | 'exerciseConfig' | 'exerciseId' | 'exerciseLoopRunning' | 'exerciseQuestionnaires' | 'exerciseTimeLeft' | 'exerciseTools' | 'exercises' | 'extendedTeamTools' | 'fileInfo' | 'groups' | 'milestones' | 'questionnaireState' | 'returnLocalEmailDraft' | 'tags' | 'team' | 'teamActionLogs' | 'teamChannelLogs' | 'teamEmailParticipant' | 'teamInjectSelections' | 'teamLearningObjectives' | 'teamMilestones' | 'teamQuestionnaires' | 'teamRoles' | 'teamTools' | 'teamUploadedFiles' | 'threadTemplate' | 'threadTemplates' | 'user' | 'users' | 'whoAmI' | QueryKeySpecifier)[];
+export type QueryKeySpecifier = ('actionLog' | 'analyticsActionLogs' | 'analyticsEmailThreads' | 'analyticsMilestones' | 'autoInjects' | 'channel' | 'definition' | 'definitions' | 'emailAddresses' | 'emailContact' | 'emailContacts' | 'emailTemplates' | 'emailThread' | 'emailThreads' | 'exerciseChannels' | 'exerciseConfig' | 'exerciseId' | 'exerciseLoopRunning' | 'exerciseQuestionnaires' | 'exerciseTimeLeft' | 'exerciseTools' | 'exercises' | 'extendedTeamTools' | 'fileInfo' | 'groups' | 'milestones' | 'questionnaireState' | 'returnLocalEmailDraft' | 'tags' | 'team' | 'teamActionLogs' | 'teamChannelLogs' | 'teamEmailParticipant' | 'teamInjectSelections' | 'teamLearningObjectives' | 'teamMilestones' | 'teamQuestionnaires' | 'teamRoles' | 'teamTools' | 'teamUploadedFiles' | 'threadTemplate' | 'threadTemplates' | 'user' | 'users' | 'validateEmailAddress' | 'whoAmI' | QueryKeySpecifier)[];
 export type QueryFieldPolicy = {
 	actionLog?: FieldPolicy<any> | FieldReadFunction<any>,
 	analyticsActionLogs?: FieldPolicy<any> | FieldReadFunction<any>,
@@ -467,6 +467,7 @@ export type QueryFieldPolicy = {
 	threadTemplates?: FieldPolicy<any> | FieldReadFunction<any>,
 	user?: FieldPolicy<any> | FieldReadFunction<any>,
 	users?: FieldPolicy<any> | FieldReadFunction<any>,
+	validateEmailAddress?: FieldPolicy<any> | FieldReadFunction<any>,
 	whoAmI?: FieldPolicy<any> | FieldReadFunction<any>
 };
 export type QuestionTypeKeySpecifier = ('control' | 'correct' | 'id' | 'labels' | 'max' | 'questionnaire' | 'text' | QuestionTypeKeySpecifier)[];
diff --git a/graphql/graphql.schema.json b/graphql/graphql.schema.json
index d443abb9c4457ff63bd00cf2fcbe8c951e7f3238..ab4a0baa19026d20d89e374f32fa352eeec546e2 100644
--- a/graphql/graphql.schema.json
+++ b/graphql/graphql.schema.json
@@ -7226,6 +7226,51 @@
             "isDeprecated": false,
             "deprecationReason": null
           },
+          {
+            "name": "validateEmailAddress",
+            "description": "Validates if the email address is valid for the specified exercise",
+            "args": [
+              {
+                "name": "address",
+                "description": null,
+                "type": {
+                  "kind": "NON_NULL",
+                  "name": null,
+                  "ofType": {
+                    "kind": "SCALAR",
+                    "name": "String",
+                    "ofType": null
+                  }
+                },
+                "defaultValue": null,
+                "isDeprecated": false,
+                "deprecationReason": null
+              },
+              {
+                "name": "exerciseId",
+                "description": null,
+                "type": {
+                  "kind": "NON_NULL",
+                  "name": null,
+                  "ofType": {
+                    "kind": "SCALAR",
+                    "name": "ID",
+                    "ofType": null
+                  }
+                },
+                "defaultValue": null,
+                "isDeprecated": false,
+                "deprecationReason": null
+              }
+            ],
+            "type": {
+              "kind": "SCALAR",
+              "name": "Boolean",
+              "ofType": null
+            },
+            "isDeprecated": false,
+            "deprecationReason": null
+          },
           {
             "name": "whoAmI",
             "description": "Retrieve data of the currently logged-in user of the request",
diff --git a/graphql/queries/ValidateEmailAddress.generated.ts b/graphql/queries/ValidateEmailAddress.generated.ts
new file mode 100644
index 0000000000000000000000000000000000000000..713366565c3772df836b63345241c4e04ebf7a5a
--- /dev/null
+++ b/graphql/queries/ValidateEmailAddress.generated.ts
@@ -0,0 +1,51 @@
+/* eslint-disable */
+//@ts-nocheck
+import type * as _Types from '../types';
+
+import type { DocumentNode } from 'graphql';
+import * as Apollo from '@apollo/client';
+const defaultOptions = {} as const;
+export type ValidateEmailAddressVariables = _Types.Exact<{
+  exerciseId: _Types.Scalars['ID']['input'];
+  address: _Types.Scalars['String']['input'];
+}>;
+
+
+export type ValidateEmailAddress = { validateEmailAddress: boolean | null };
+
+
+export const ValidateEmailAddressDocument = /*#__PURE__*/ {"kind":"Document","definitions":[{"kind":"OperationDefinition","operation":"query","name":{"kind":"Name","value":"ValidateEmailAddress"},"variableDefinitions":[{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"exerciseId"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"ID"}}}},{"kind":"VariableDefinition","variable":{"kind":"Variable","name":{"kind":"Name","value":"address"}},"type":{"kind":"NonNullType","type":{"kind":"NamedType","name":{"kind":"Name","value":"String"}}}}],"selectionSet":{"kind":"SelectionSet","selections":[{"kind":"Field","name":{"kind":"Name","value":"validateEmailAddress"},"arguments":[{"kind":"Argument","name":{"kind":"Name","value":"exerciseId"},"value":{"kind":"Variable","name":{"kind":"Name","value":"exerciseId"}}},{"kind":"Argument","name":{"kind":"Name","value":"address"},"value":{"kind":"Variable","name":{"kind":"Name","value":"address"}}}]}]}}]} as unknown as DocumentNode;
+
+/**
+ * __useValidateEmailAddress__
+ *
+ * To run a query within a React component, call `useValidateEmailAddress` and pass it any options that fit your needs.
+ * When your component renders, `useValidateEmailAddress` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useValidateEmailAddress({
+ *   variables: {
+ *      exerciseId: // value for 'exerciseId'
+ *      address: // value for 'address'
+ *   },
+ * });
+ */
+export function useValidateEmailAddress(baseOptions: Apollo.QueryHookOptions<ValidateEmailAddress, ValidateEmailAddressVariables> & ({ variables: ValidateEmailAddressVariables; skip?: boolean; } | { skip: boolean; }) ) {
+        const options = {...defaultOptions, ...baseOptions}
+        return Apollo.useQuery<ValidateEmailAddress, ValidateEmailAddressVariables>(ValidateEmailAddressDocument, options);
+      }
+export function useValidateEmailAddressLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions<ValidateEmailAddress, ValidateEmailAddressVariables>) {
+          const options = {...defaultOptions, ...baseOptions}
+          return Apollo.useLazyQuery<ValidateEmailAddress, ValidateEmailAddressVariables>(ValidateEmailAddressDocument, options);
+        }
+export function useValidateEmailAddressSuspenseQuery(baseOptions?: Apollo.SuspenseQueryHookOptions<ValidateEmailAddress, ValidateEmailAddressVariables>) {
+          const options = {...defaultOptions, ...baseOptions}
+          return Apollo.useSuspenseQuery<ValidateEmailAddress, ValidateEmailAddressVariables>(ValidateEmailAddressDocument, options);
+        }
+export type ValidateEmailAddressHookResult = ReturnType<typeof useValidateEmailAddress>;
+export type ValidateEmailAddressLazyQueryHookResult = ReturnType<typeof useValidateEmailAddressLazyQuery>;
+export type ValidateEmailAddressSuspenseQueryHookResult = ReturnType<typeof useValidateEmailAddressSuspenseQuery>;
+export type ValidateEmailAddressQueryResult = Apollo.QueryResult<ValidateEmailAddress, ValidateEmailAddressVariables>;
\ No newline at end of file
diff --git a/graphql/types.ts b/graphql/types.ts
index b392dd2c6575adb797ff2d6665e824d993c6169f..4f0ab216dbb93e370d324e1281256c89761ddb3a 100644
--- a/graphql/types.ts
+++ b/graphql/types.ts
@@ -811,6 +811,8 @@ export type Query = {
   user?: Maybe<UserType>;
   /** Retrieve all users with filtering options */
   users?: Maybe<Array<Maybe<UserType>>>;
+  /** Validates if the email address is valid for the specified exercise */
+  validateEmailAddress?: Maybe<Scalars['Boolean']['output']>;
   /** Retrieve data of the currently logged-in user of the request */
   whoAmI?: Maybe<UserType>;
 };
@@ -1019,6 +1021,12 @@ export type QueryUsersArgs = {
   filterUsersInput?: InputMaybe<FilterUsersInput>;
 };
 
+
+export type QueryValidateEmailAddressArgs = {
+  address: Scalars['String']['input'];
+  exerciseId: Scalars['ID']['input'];
+};
+
 export type QuestionType = {
   control: ControlType;
   correct: Scalars['Int']['output'];
@@ -2179,6 +2187,7 @@ export type QueryResolvers<ContextType = any, ParentType extends ResolversParent
   threadTemplates?: Resolver<Maybe<Array<Maybe<ResolversTypes['EmailTemplateType']>>>, ParentType, ContextType, RequireFields<QueryThreadTemplatesArgs, 'threadId'>>;
   user?: Resolver<Maybe<ResolversTypes['UserType']>, ParentType, ContextType, Partial<QueryUserArgs>>;
   users?: Resolver<Maybe<Array<Maybe<ResolversTypes['UserType']>>>, ParentType, ContextType, Partial<QueryUsersArgs>>;
+  validateEmailAddress?: Resolver<Maybe<ResolversTypes['Boolean']>, ParentType, ContextType, RequireFields<QueryValidateEmailAddressArgs, 'address' | 'exerciseId'>>;
   whoAmI?: Resolver<Maybe<ResolversTypes['UserType']>, ParentType, ContextType>;
 }>;