diff --git a/greg/api/serializers/invitation.py b/greg/api/serializers/invitation.py
index 820e51979548a180c02fe80630ada93aaf7f8c5b..c169fea1c89d862606a250b2dde6f8bfdd11febb 100644
--- a/greg/api/serializers/invitation.py
+++ b/greg/api/serializers/invitation.py
@@ -1,13 +1,8 @@
-from datetime import timedelta
-
 from rest_framework import serializers
-from django.conf import settings
-from django.db import transaction
-from django.utils import timezone
 
 from greg.api.serializers.role import RoleInvitationSerializer
-from greg.models import Identity, Invitation, InvitationLink, Person, Role, Sponsor
-from greg.utils import is_identity_duplicate
+from greg.models import Identity, Person, Sponsor
+from greg.utils import create_objects_for_invitation, is_identity_duplicate
 from gregui.api.serializers.identity import IdentityDuplicateError
 
 
@@ -21,29 +16,19 @@ class InvitationSerializer(serializers.ModelSerializer):
         role_data = validated_data.pop("role")
         sponsor = validated_data.pop("sponsor")
 
-        with transaction.atomic():
-            # Find sponsor based on feide_id
-            # If not found create sponsor with feide_id instead
-            try:
-                sponsor = Sponsor.objects.get(feide_id=sponsor)
-            except Sponsor.DoesNotExist:
-                sponsor = Sponsor.objects.create(feide_id=sponsor)
-
-            person = Person.objects.create(**validated_data)
-            Identity.objects.create(
-                person=person,
-                type=Identity.IdentityType.PRIVATE_EMAIL,
-                value=email,
-                source=settings.DEFAULT_IDENTITY_SOURCE,
-            )
-            role_data["person"] = person
-            role_data["sponsor"] = sponsor
-            role = Role.objects.create(**role_data)
-            invitation = Invitation.objects.create(role=role)
-            InvitationLink.objects.create(
-                invitation=invitation,
-                expire=timezone.now() + timedelta(days=30),
-            )
+        # Find sponsor based on feide_id
+        # If not found it will be created
+        try:
+            sponsor = Sponsor.objects.get(feide_id=sponsor)
+        except Sponsor.DoesNotExist:
+            pass
+
+        person = create_objects_for_invitation(
+            person_data=validated_data,
+            person_email=email,
+            role_data=role_data,
+            sponsor=sponsor,
+        )
 
         return person
 
diff --git a/greg/api/views/invitation.py b/greg/api/views/invitation.py
index 5924832087f99d47a15a26a1496b03328472ac1e..ced0f05ece6512d8d0a87319180bf8c48c8b914d 100644
--- a/greg/api/views/invitation.py
+++ b/greg/api/views/invitation.py
@@ -2,8 +2,8 @@ from rest_framework import permissions, status, viewsets
 from rest_framework.response import Response
 
 from greg.api.serializers.invitation import InvitationSerializer
-from greg.models import InvitationLink, Sponsor
-from gregui.mailutils.invite_guest import InviteGuest
+from greg.models import Sponsor
+from greg.utils import queue_mail_to_invitee
 
 
 class InvitationViewSet(viewsets.ModelViewSet):
@@ -21,12 +21,7 @@ class InvitationViewSet(viewsets.ModelViewSet):
         sponsor_feide_id = serializer.validated_data["sponsor"]
         sponsor = Sponsor.objects.get(feide_id=sponsor_feide_id)
 
-        for invitationlink in InvitationLink.objects.filter(
-            invitation__role__person_id=person.id,
-            invitation__role__sponsor_id=sponsor.id,
-        ):
-            invitemailer = InviteGuest()
-            invitemailer.queue_mail(invitationlink)
+        queue_mail_to_invitee(person, sponsor)
 
         headers = self.get_success_headers(serializer.validated_data)
         return Response(status=status.HTTP_201_CREATED, headers=headers)
diff --git a/greg/utils.py b/greg/utils.py
index 1afb6f20868692dc182eafb561eb94b0df43dbae..c051a7f6b299657b1e5351f579d4e0521f475c3e 100644
--- a/greg/utils.py
+++ b/greg/utils.py
@@ -1,10 +1,19 @@
 import re
 import typing
 from datetime import date, datetime, timedelta
+from django.db import transaction
 from django.conf import settings
 from django.utils import timezone
 
-from greg.models import Identity
+from greg.models import (
+    Identity,
+    Invitation,
+    InvitationLink,
+    Person,
+    Role,
+    Sponsor,
+)
+from gregui.mailutils.invite_guest import InviteGuest
 
 
 def camel_to_snake(s: str) -> str:
@@ -120,3 +129,44 @@ def get_default_invitation_expire_date_from_now():
 
 def is_identity_duplicate(identity_type: Identity.IdentityType, value: str) -> bool:
     return Identity.objects.filter(type=identity_type).filter(value=value).exists()
+
+
+def create_objects_for_invitation(
+    person_data: dict,
+    person_email: str,
+    role_data: dict,
+    sponsor: typing.Union[Sponsor, str],
+) -> Person:
+
+    with transaction.atomic():
+
+        # If only sponsor's feide_id is provided create the sponsor
+        if isinstance(sponsor, str):
+            sponsor = Sponsor.objects.create(feide_id=sponsor)
+
+        person = Person.objects.create(**person_data)
+        Identity.objects.create(
+            person=person,
+            type=Identity.IdentityType.PRIVATE_EMAIL,
+            value=person_email,
+            source=settings.DEFAULT_IDENTITY_SOURCE,
+        )
+        role_data["person"] = person
+        role_data["sponsor"] = sponsor
+        role = Role.objects.create(**role_data)
+        invitation = Invitation.objects.create(role=role)
+        InvitationLink.objects.create(
+            invitation=invitation,
+            expire=timezone.now() + timedelta(days=30),
+        )
+
+    return person
+
+
+def queue_mail_to_invitee(person: Person, sponsor: Sponsor):
+    for invitationlink in InvitationLink.objects.filter(
+        invitation__role__person_id=person.id,
+        invitation__role__sponsor_id=sponsor.id,
+    ):
+        invitemailer = InviteGuest()
+        invitemailer.queue_mail(invitationlink)
diff --git a/gregui/api/serializers/invitation.py b/gregui/api/serializers/invitation.py
index 1673de9b812946258b517459da4689ae7c9344ac..add333aa7655ec35efd159134c7f9e32ab466584 100644
--- a/gregui/api/serializers/invitation.py
+++ b/gregui/api/serializers/invitation.py
@@ -1,12 +1,7 @@
-import datetime
-
-from django.conf import settings
-from django.db import transaction
-from django.utils import timezone
 from rest_framework import serializers
 
-from greg.models import Invitation, InvitationLink, Person, Role, Identity
-from greg.utils import is_identity_duplicate
+from greg.models import Person, Identity
+from greg.utils import create_objects_for_invitation, is_identity_duplicate
 from gregui.api.serializers.identity import IdentityDuplicateError
 from gregui.api.serializers.role import InviteRoleSerializerUi
 from gregui.models import GregUserProfile
@@ -21,25 +16,17 @@ class InviteGuestSerializer(serializers.ModelSerializer):
         email = validated_data.pop("email")
         role_data = validated_data.pop("role")
 
-        user = GregUserProfile.objects.get(user=self.context["request"].user)
+        user_str = self.context["request"].user
+        user = GregUserProfile.objects.get(user=user_str)
+        sponsor = user.sponsor
+
+        person = create_objects_for_invitation(
+            person_data=validated_data,
+            person_email=email,
+            role_data=role_data,
+            sponsor=sponsor,
+        )
 
-        # Create objects
-        with transaction.atomic():
-            person = Person.objects.create(**validated_data)
-            Identity.objects.create(
-                person=person,
-                type=Identity.IdentityType.PRIVATE_EMAIL,
-                value=email,
-                source=settings.DEFAULT_IDENTITY_SOURCE,
-            )
-            role_data["person"] = person
-            role_data["sponsor"] = user.sponsor
-            role = Role.objects.create(**role_data)
-            invitation = Invitation.objects.create(role=role)
-            InvitationLink.objects.create(
-                invitation=invitation,
-                expire=timezone.now() + datetime.timedelta(days=30),
-            )
         return person
 
     def validate_email(self, email):
diff --git a/gregui/api/views/invitation.py b/gregui/api/views/invitation.py
index cadd633dc128f23b2cd937345b326ddf41d61f39..5832a675cce2f3bce679bdda0787f2ffb8c54e68 100644
--- a/gregui/api/views/invitation.py
+++ b/gregui/api/views/invitation.py
@@ -20,7 +20,10 @@ from rest_framework.views import APIView
 
 from greg.models import Identity, InvitationLink, Person
 from greg.permissions import IsSponsor
-from greg.utils import get_default_invitation_expire_date_from_now
+from greg.utils import (
+    get_default_invitation_expire_date_from_now,
+    queue_mail_to_invitee,
+)
 from gregui.api.serializers.guest import GuestRegisterSerializer
 from gregui.api.serializers.invitation import InviteGuestSerializer
 from gregui.mailutils.confirm_guest import ConfirmGuest
@@ -67,19 +70,17 @@ class InvitationView(CreateAPIView, DestroyAPIView):
         information, and confirm it.
         """
         sponsor_user = GregUserProfile.objects.get(user=request.user)
+        sponsor = sponsor_user.sponsor
+
         serializer = self.serializer_class(
             data=request.data,
-            context={"request": request, "sponsor": sponsor_user.sponsor},
+            context={"request": request, "sponsor": sponsor},
         )
         serializer.is_valid(raise_exception=True)
         person = serializer.save()
 
-        for invitationlink in InvitationLink.objects.filter(
-            invitation__role__person_id=person.id,
-            invitation__role__sponsor_id=sponsor_user.sponsor_id,
-        ):
-            invitemailer = InviteGuest()
-            invitemailer.queue_mail(invitationlink)
+        queue_mail_to_invitee(person, sponsor)
+
         # Empty json-body to avoid client complaining about non-json data in response
         return Response(status=status.HTTP_201_CREATED, data={})