diff --git a/README.md b/README.md
index a6babf2d45d8b8fb38759ff195aecb6f07ba523c..b9b8f371b6c9c7021a05801e0c3b8572979ff899 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,5 @@
 # Greg
+
 [![pipeline status](https://git.app.uib.no/it-bott-integrasjoner/greg/badges/master/pipeline.svg)](https://git.app.uib.no/it-bott-integrasjoner/greg/-/commits/master)
 [![coverage report](https://git.app.uib.no/it-bott-integrasjoner/greg/badges/master/coverage.svg)](https://git.app.uib.no/it-bott-integrasjoner/greg/-/commits/master)
 
@@ -50,6 +51,13 @@ Use pytest with the pytest-django library to run unit tests.
 
     pytest
 
+There are two scripts for adding data to the database:
+
+- greg/tests/populate_fixtures.py
+- greg/tests/populate_database.py
+
+where the former uses randomized data, and the latter uses specific data useful in combination with the frontend. See the respective files for how to use them.
+
 ## Static type analysis
 
 Use [mypy](http://mypy-lang.org/) to run static type checks using type hints.
diff --git a/frontend/public/locales/en/common.json b/frontend/public/locales/en/common.json
index 4d6d0bf2af6583d41c2c630476eb13148598dab0..ede4d0c0abe71ae84669845f6c1df1dddcce0049 100644
--- a/frontend/public/locales/en/common.json
+++ b/frontend/public/locales/en/common.json
@@ -24,7 +24,8 @@
     "mobilePhone": "Mobile phone",
     "passportNumber": "Passport number",
     "passportNationality": "Passport nationality",
-    "countryCallingCode": "Country code"
+    "countryCallingCode": "Country code",
+    "contactPersonUnit": "Contact at unit"
   },
   "sponsor": {
     "addRole": "Add role",
@@ -86,7 +87,9 @@
     "invalidMobilePhoneNumber": "Invalid phone number",
     "invalidEmail": "Invalid e-mail address",
     "passportNumberRequired": "Passport number required",
-    "mobilePhoneRequired": "Mobile phone is required"
+    "mobilePhoneRequired": "Mobile phone is required",
+    "startDateMustBeSet": "Start date must be set",
+    "startDateMustBeBeforeEndDate": "Start date has to be before end date"
   },
   "button": {
     "back": "Back",
diff --git a/frontend/public/locales/nb/common.json b/frontend/public/locales/nb/common.json
index 0054273107f3395a1ece25ff3c06bfe755eb3d49..d9e825659c3f14bac22fd9adf4041152a426a3ec 100644
--- a/frontend/public/locales/nb/common.json
+++ b/frontend/public/locales/nb/common.json
@@ -24,7 +24,8 @@
     "mobilePhone": "Mobilnummer",
     "passportNumber": "Passnummer",
     "passportNationality": "Passnasjonalitet",
-    "countryCallingCode": "Landkode"
+    "countryCallingCode": "Landkode",
+    "contactPersonUnit": "Kontakt ved avdeling"
   },
   "sponsor": {
     "addRole": "Legg til rolle",
@@ -86,7 +87,9 @@
     "invalidMobilePhoneNumber": "Ugyldig telefonnummer",
     "invalidEmail": "Ugyldig e-postadresse",
     "passportNumberRequired": "Passnummer er obligatorisk",
-    "mobilePhoneRequired": "Mobilnummer er obligatorisk"
+    "mobilePhoneRequired": "Mobilnummer er obligatorisk",
+    "startDateMustBeSet": "Startdato må være satt",
+    "startDateMustBeBeforeEndDate": "Startdato må være før sluttdato"
   },
   "button": {
     "back": "Tilbake",
diff --git a/frontend/public/locales/nn/common.json b/frontend/public/locales/nn/common.json
index cc1da0d414515fe44ab177ed74a0eaae6415a69b..36c4ce1e4dd26a18b37b0c06500a5b0ed2184efa 100644
--- a/frontend/public/locales/nn/common.json
+++ b/frontend/public/locales/nn/common.json
@@ -25,7 +25,8 @@
     "mobilePhone": "Mobilnummer",
     "passportNumber": "Passnummer",
     "passportNationality": "Passnasjonalitet",
-    "countryCallingCode": "Landkode"
+    "countryCallingCode": "Landkode",
+    "contactPersonUnit": "Kontakt ved avdeling"
   },
   "sponsor": {
     "addRole": "Legg til role",
@@ -87,7 +88,9 @@
     "invalidMobilePhoneNumber": "Ugyldig telefonnummer",
     "invalidEmail": "Ugyldig e-postadresse",
     "passportNumberRequired": "Passnummer er obligatorisk",
-    "mobilePhoneRequired": "Mobilnummer er obligatorisk"
+    "mobilePhoneRequired": "Mobilnummer er obligatorisk",
+    "startDateMustBeSet": "Startdato må vere satt",
+    "startDateMustBeBeforeEndDate": "Startdato må vere før sluttdato"
   },
   "button": {
     "back": "Tilbake",
diff --git a/frontend/src/routes/sponsor/frontpage/index.tsx b/frontend/src/routes/sponsor/frontpage/index.tsx
index 0f35c19a0716f54aa3603b6304b9ca4bc383f858..3c9ecdee9af823f2a4c185192a248c944e7694e1 100644
--- a/frontend/src/routes/sponsor/frontpage/index.tsx
+++ b/frontend/src/routes/sponsor/frontpage/index.tsx
@@ -18,7 +18,8 @@ import Page from 'components/page'
 import { useTranslation } from 'react-i18next'
 import { Link } from 'react-router-dom'
 import { Guest, Role } from 'interfaces'
-import format from 'date-fns/format'
+import { isBefore, format } from 'date-fns'
+
 import SponsorGuestButtons from '../../components/sponsorGuestButtons'
 
 interface GuestProps {
@@ -33,7 +34,8 @@ interface PersonLineProps {
 
 const PersonLine = ({ person, role, showStatusColumn }: PersonLineProps) => {
   const [t, i18n] = useTranslation(['common'])
-
+  const today = new Date()
+  today.setHours(0, 0, 0, 0)
   return (
     <TableRow
       key={`${person.first} ${person.last}`}
@@ -47,7 +49,7 @@ const PersonLine = ({ person, role, showStatusColumn }: PersonLineProps) => {
       </TableCell>
 
       {showStatusColumn &&
-        (person.active ? (
+        (!isBefore(role.end_date, today) ? (
           <TableCell sx={{ color: 'green' }} align="left">
             {t('common:active')}
           </TableCell>
diff --git a/frontend/src/routes/sponsor/register/formData.ts b/frontend/src/routes/sponsor/register/formData.ts
index 5e518b30d580c96186d66215ae12c4c6a77d3cda..8e96d7a625f1da93f7e34360939c4ccb0f267cb9 100644
--- a/frontend/src/routes/sponsor/register/formData.ts
+++ b/frontend/src/routes/sponsor/register/formData.ts
@@ -4,6 +4,7 @@ export type RegisterFormData = {
   role_type?: string
   role_start?: Date
   role_end?: Date
+  contact_person_unit?: string
   comment?: string
   ou_id?: number
   email?: string
diff --git a/frontend/src/routes/sponsor/register/stepPersonForm.tsx b/frontend/src/routes/sponsor/register/stepPersonForm.tsx
index bbfd2431a8f3b5a200e865dd451bd7f203a08fa4..c13e7b5e541a58e145e2c1db3dee6e70cc220e69 100644
--- a/frontend/src/routes/sponsor/register/stepPersonForm.tsx
+++ b/frontend/src/routes/sponsor/register/stepPersonForm.tsx
@@ -62,6 +62,7 @@ const StepPersonForm = forwardRef(
       formState: { errors },
       reset,
       setValue,
+      getValues,
     } = useForm<RegisterFormData>()
     const onSubmit = handleSubmit(submit)
 
@@ -93,6 +94,19 @@ const StepPersonForm = forwardRef(
 
     useImperativeHandle(ref, () => ({ doSubmit }))
 
+    const validateStartDateBeforeEndDate = (startDate: Date | undefined) => {
+      if (!startDate) {
+        return t('validation.startDateMustBeSet')
+      }
+
+      const roleEnd = getValues('role_end')
+      if (roleEnd && startDate > roleEnd) {
+        // The role end date is set, but is is before the start date
+        return t('validation.startDateMustBeBeforeEndDate')
+      }
+      return true
+    }
+
     return (
       <>
         <Typography
@@ -185,9 +199,11 @@ const StepPersonForm = forwardRef(
                 ))}
               </TextField>
 
+              {/* There are no particular constraints on the date pickers. It should be allowed to add a role with a start date that is in the past for instance */}
               <Controller
                 name="role_start"
                 control={control}
+                rules={{ validate: validateStartDateBeforeEndDate }}
                 render={({ field }) => (
                   <DatePicker
                     mask="____-__-__"
@@ -201,7 +217,11 @@ const StepPersonForm = forwardRef(
                   />
                 )}
               />
-
+              {!!errors.role_start && (
+                <Box sx={{ typography: 'caption', color: 'red' }}>
+                  {errors.role_start.message}
+                </Box>
+              )}
               <Controller
                 name="role_end"
                 control={control}
@@ -219,6 +239,12 @@ const StepPersonForm = forwardRef(
                 )}
               />
 
+              <TextField
+                id="contact_person"
+                label={t('input.contactPersonUnit')}
+                {...register(`contact_person_unit`)}
+              />
+
               <TextField
                 id="comment"
                 label={t('input.comment')}
diff --git a/frontend/src/routes/sponsor/register/stepRegistration.tsx b/frontend/src/routes/sponsor/register/stepRegistration.tsx
index 8e4bd716e21d118d6f5c2dfdafad4f01ffe38319..36ba38bb127bcd61b14376ad435d4076febd99f3 100644
--- a/frontend/src/routes/sponsor/register/stepRegistration.tsx
+++ b/frontend/src/routes/sponsor/register/stepRegistration.tsx
@@ -70,6 +70,7 @@ export default function StepRegistration() {
           formData.role_end === null
             ? null
             : format(formData.role_end as Date, 'yyyy-MM-dd'),
+        contact_person_unit: formData.contact_person_unit,
         comments: formData.comment,
         orgunit: formData.ou_id,
       },
diff --git a/greg/management/commands/import_from_orgreg.py b/greg/management/commands/import_from_orgreg.py
index 732a68206ba4bb8599e3de7c7cc4d8972cff9367..2411ed04921d25484d88af2c451043c80b262504 100644
--- a/greg/management/commands/import_from_orgreg.py
+++ b/greg/management/commands/import_from_orgreg.py
@@ -28,6 +28,75 @@ class Command(BaseCommand):
     help = __doc__
     processed: Dict[int, OrganizationalUnit] = {}
 
+    def _upsert_extra_identities(
+        self,
+        ou: OrgUnit,
+    ):
+        """Upsert any configured extra IDs from orgreg."""
+        for extra_id in settings.ORGREG_EXTRA_IDS:
+
+            matching_ids = [
+                x
+                for x in ou.external_keys
+                if x.source_system == extra_id["source"] and x.type == extra_id["type"]
+            ]
+
+            if not matching_ids:
+                logger.warning(
+                    "No %s id from %s found in OrgReg for ou %s",
+                    extra_id["type"],
+                    extra_id["source"],
+                    ou.ou_id,
+                )
+                continue
+
+            if len(matching_ids) > 1:
+                # External_ids
+                logger.warning(
+                    "Found multiple ids matching type: %s source: %s in OrgReg. Using the first one: %s",
+                    extra_id["type"],
+                    extra_id["source"],
+                    matching_ids[0].value,
+                )
+
+            identity_in_orgreg = matching_ids[0]
+
+            # Check if the id exists
+            identify_in_db = (
+                self.processed[ou.ou_id]
+                .identifiers.filter(
+                    source=extra_id["source"],
+                    name=extra_id["type"],
+                )
+                .first()
+            )
+
+            if identify_in_db:
+                if identify_in_db.value != identity_in_orgreg.value:
+                    logger.info(
+                        "Updating id: source: %s, type: %s, old_id: %s, new_id %s",
+                        extra_id["source"],
+                        extra_id["type"],
+                        identify_in_db.value,
+                        identity_in_orgreg.value,
+                    )
+                    identify_in_db.value = identity_in_orgreg.value
+                    identify_in_db.save()
+            else:
+                OuIdentifier.objects.create(
+                    name=extra_id["type"],
+                    source=extra_id["source"],
+                    value=identity_in_orgreg["value"],
+                    orgunit=self.processed[ou.ou_id],
+                )
+                logger.info(
+                    "Added new id to ou: %s, type: %s, source: %s value: %s",
+                    ou.ou_id,
+                    extra_id["type"],
+                    extra_id["source"],
+                    identity_in_orgreg["value"],
+                )
+
     def _get_or_create_and_set_values(
         self, ou: OrgUnit, values: Mapping[str, Union[str, int, bool]]
     ):
@@ -50,6 +119,7 @@ class Command(BaseCommand):
             created = False
         for k, v in values.items():
             setattr(self.processed[ou.ou_id], k, v)
+        self._upsert_extra_identities(ou)
         self.processed[ou.ou_id].save()
         logger.info(
             "%s %s with %s",
diff --git a/greg/models.py b/greg/models.py
index 8948adb47f0195d473717e8eb342eb21d88d2a02..58ed1c2e3ca065b9bc8bc9dbc0aaa19e8366838a 100644
--- a/greg/models.py
+++ b/greg/models.py
@@ -83,6 +83,14 @@ class Person(BaseModel):
             type=Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER
         ).first()
 
+    @property
+    def passport(self) -> Optional["Identity"]:
+        """The person's passport if they have one registered.
+        This property was introduced to make updating of passport easier when the guest registers himself."""
+        return self.identities.filter(
+            type=Identity.IdentityType.PASSPORT_NUMBER
+        ).first()
+
     @property
     def is_registered(self) -> bool:
         """
diff --git a/greg/tests/populate_fixtures.py b/greg/tests/populate_fixtures.py
new file mode 100644
index 0000000000000000000000000000000000000000..d7e03f4ed11a58a702c93944b76be8d384b513c7
--- /dev/null
+++ b/greg/tests/populate_fixtures.py
@@ -0,0 +1,343 @@
+"""
+Adds a few more specific models for testing purposes. Alternative to the similiar
+script for adding random data to various fields.
+
+WARNING: This script removes all entries in most tables. Do not execute it unless you
+are absolutely certain you know what you are doing.
+
+There are 4 guests:
+  - One has been invited and not done anything yet
+  - One has followed the invite link and provided a passport number, and is waiting for
+    the sponsor to act
+  - One has had their passport number confirmed by the sponsor and the role is active
+  - One like the previous but the role has ended
+
+There is an OU tree with 4 OUs on three levels, with respective OUIdentifiers.
+There is an invitation object related to each guest with InvitationLinks that are
+expired for all but they invited guest that has not responded.
+
+There are Consent Types, and the active guests have consented to the mandatory one, but
+one of them has denied the other one.
+
+"""
+
+import datetime
+import logging
+
+from django.db import connection
+from django.conf import settings
+from django.utils import timezone
+
+from greg.models import (
+    Consent,
+    ConsentType,
+    Identity,
+    Invitation,
+    InvitationLink,
+    OrganizationalUnit,
+    OuIdentifier,
+    Person,
+    Role,
+    RoleType,
+    Sponsor,
+    SponsorOrganizationalUnit,
+)
+
+
+ROLE_TYPE_EXT_SCI = "extsci"
+ROLE_TYPE_EMERITUS = "emeritus"
+TESTDATA_SOURCE = "testsource"
+SPONSOR_FEIDEID = "sponsor@feide.no"
+OU_EUROPE_NAME_EN = "Europe"
+CONSENT_IDENT_MANDATORY = "mandatory"
+CONSENT_IDENT_OPTIONAL = "optional"
+
+logger = logging.getLogger(__name__)
+
+
+class DatabasePopulation:
+    """
+    Helper class for populating database with specific data
+
+    Run the file in the Django shell: exec(open('greg/tests/populate_fixtures.py').read())
+    """
+
+    def truncate_tables(self):
+        logger.info("truncating tables...")
+        with connection.cursor() as cursor:
+            for table in (
+                "greg_consent",
+                "greg_consenttype",
+                "greg_notification",
+                "greg_identity",
+                "greg_invitationlink",
+                "greg_invitation",
+                "greg_role",
+                "greg_sponsororganizationalunit",
+                "greg_roletype",
+                "greg_ouidentifier",
+                "greg_organizationalunit",
+                "greg_person",
+                "gregui_greguserprofile",
+                "greg_sponsor",
+            ):
+                logging.info("purging table %s", table)
+                cursor.execute(f"DELETE FROM {table}")
+        logger.info("...tables purged")
+
+    def _add_consenttypes(self):
+        ConsentType.objects.create(
+            identifier=CONSENT_IDENT_MANDATORY,
+            name_en="Mandatory consent type",
+            name_nb="PÃ¥krevd samtykketype",
+            user_allowed_to_change=False,
+            mandatory=True,
+        )
+        ConsentType.objects.create(
+            identifier=CONSENT_IDENT_OPTIONAL,
+            name_en="Optional consent type",
+            name_nb="Valgfri samtykketype",
+            user_allowed_to_change=False,
+        )
+
+    def _add_ous_with_identifiers(self):
+        """
+        Create a simple tree
+
+        earth - america
+              - europe - norway
+        """
+        earth = OrganizationalUnit.objects.create(
+            name_nb="Universitetet i Jorden", name_en="University of Earth"
+        )
+        OuIdentifier.objects.create(
+            name=settings.ORGREG_NAME,
+            source=settings.ORGREG_SOURCE,
+            value="2",
+            orgunit=earth,
+        )
+        europe = OrganizationalUnit.objects.create(
+            name_nb="Europa", name_en=OU_EUROPE_NAME_EN, parent=earth
+        )
+        OuIdentifier.objects.create(
+            name=settings.ORGREG_NAME,
+            source=settings.ORGREG_SOURCE,
+            value="3",
+            orgunit=europe,
+        )
+        america = OrganizationalUnit.objects.create(
+            name_nb="Amerika", name_en="America", parent=earth
+        )
+        OuIdentifier.objects.create(
+            name=settings.ORGREG_NAME,
+            source=settings.ORGREG_SOURCE,
+            value="4",
+            orgunit=america,
+        )
+        norway = OrganizationalUnit.objects.create(
+            name_nb="Norge", name_en="Norway", parent=europe
+        )
+        OuIdentifier.objects.create(
+            name=settings.ORGREG_NAME,
+            source=settings.ORGREG_SOURCE,
+            value="5",
+            orgunit=norway,
+        )
+
+    def _add_roletypes(self):
+        RoleType.objects.create(
+            identifier=ROLE_TYPE_EXT_SCI,
+            name_nb="Gjesteforsker",
+            name_en="Guest researcher",
+            description_nb="Gjesteforsker som ikke skal ha lønn",
+            description_en="Guest reasearcher without payment",
+        )
+        RoleType.objects.create(
+            identifier=ROLE_TYPE_EMERITUS,
+            name_nb="Emeritus",
+            name_en="Emeritus",
+            description_nb="Emeritus",
+            description_en="Emeritus",
+            max_days=700,
+        )
+
+    def _add_sponsors(self):
+        """Add a sponsor connected to the Europe unit"""
+        sam = Sponsor.objects.create(
+            feide_id=SPONSOR_FEIDEID, first_name="Sam", last_name="Sponsorson"
+        )
+        SponsorOrganizationalUnit.objects.create(
+            sponsor=sam,
+            organizational_unit=OrganizationalUnit.objects.get(
+                name_en=OU_EUROPE_NAME_EN
+            ),
+            hierarchical_access=False,
+        )
+
+    def _add_invited_person(self):
+        """Person that has been invited and has not followed their invite"""
+        iggy = Person.objects.create(first_name="Iggy", last_name="Invited")
+        role = Role.objects.create(
+            person=iggy,
+            type=RoleType.objects.get(identifier=ROLE_TYPE_EXT_SCI),
+            orgunit=OrganizationalUnit.objects.get(name_en=OU_EUROPE_NAME_EN),
+            start_date=datetime.date.today() + datetime.timedelta(days=2),
+            end_date=datetime.date.today() + datetime.timedelta(days=100),
+            sponsor=Sponsor.objects.get(feide_id=SPONSOR_FEIDEID),
+        )
+        invitation = Invitation.objects.create(
+            role=role,
+        )
+        InvitationLink.objects.create(
+            invitation=invitation,
+            expire=timezone.now() + datetime.timedelta(days=30),
+        )
+
+    def _add_waiting_person(self):
+        """
+        A person with an active role but missing a verified identity of type national
+        id or passport.
+        """
+        walter = Person.objects.create(
+            first_name="Walter",
+            last_name="Waiting",
+            registration_completed_date=datetime.date.today()
+            - datetime.timedelta(days=10),
+        )
+        role = Role.objects.create(
+            person=walter,
+            type=RoleType.objects.get(identifier=ROLE_TYPE_EXT_SCI),
+            orgunit=OrganizationalUnit.objects.get(name_en=OU_EUROPE_NAME_EN),
+            start_date=datetime.date.today() - datetime.timedelta(days=30),
+            end_date=datetime.date.today() + datetime.timedelta(days=100),
+            sponsor=Sponsor.objects.get(feide_id=SPONSOR_FEIDEID),
+        )
+        Identity.objects.create(
+            person=walter,
+            type=Identity.IdentityType.PASSPORT_NUMBER,
+            source=TESTDATA_SOURCE,
+            value="SE-123456789",
+        )
+        invitation = Invitation.objects.create(
+            role=role,
+        )
+        InvitationLink.objects.create(
+            invitation=invitation,
+            expire=timezone.now() - datetime.timedelta(days=35),
+        )
+
+    def _add_active_person(self):
+        """
+        A person with an active role and a verified identity of type national id or
+        passport.
+        """
+        adam = Person.objects.create(
+            first_name="Adam",
+            last_name="Active",
+            registration_completed_date=datetime.date.today()
+            - datetime.timedelta(days=10),
+        )
+        role = Role.objects.create(
+            person=adam,
+            type=RoleType.objects.get(identifier=ROLE_TYPE_EXT_SCI),
+            orgunit=OrganizationalUnit.objects.get(name_en=OU_EUROPE_NAME_EN),
+            start_date=datetime.date.today() - datetime.timedelta(days=30),
+            end_date=datetime.date.today() + datetime.timedelta(days=100),
+            sponsor=Sponsor.objects.get(feide_id=SPONSOR_FEIDEID),
+        )
+        Identity.objects.create(
+            person=adam,
+            type=Identity.IdentityType.PASSPORT_NUMBER,
+            source=TESTDATA_SOURCE,
+            value="NO-123456789",
+            verified_at=timezone.now() - datetime.timedelta(days=31),
+        )
+        Identity.objects.create(
+            person=adam,
+            type=Identity.IdentityType.PRIVATE_MOBILE_NUMBER,
+            source=TESTDATA_SOURCE,
+            value="+4792492412",
+            verified_at=timezone.now() - datetime.timedelta(days=205),
+        )
+        invitation = Invitation.objects.create(
+            role=role,
+        )
+        InvitationLink.objects.create(
+            invitation=invitation,
+            expire=timezone.now() - datetime.timedelta(days=32),
+        )
+        Consent.objects.create(
+            person=adam,
+            type=ConsentType.objects.get(identifier=CONSENT_IDENT_MANDATORY),
+            consent_given_at=datetime.date.today() - datetime.timedelta(days=10),
+        )
+        Consent.objects.create(
+            person=adam,
+            type=ConsentType.objects.get(identifier=CONSENT_IDENT_OPTIONAL),
+            consent_given_at=datetime.date.today() - datetime.timedelta(days=10),
+        )
+
+    def _add_expired_person(self):
+        """
+        A person with an inactive role, and a verified identity of type national id or
+        passport.
+        """
+        esther = Person.objects.create(
+            first_name="Esther",
+            last_name="Expired",
+            registration_completed_date=timezone.now() - datetime.timedelta(days=206),
+        )
+        role = Role.objects.create(
+            person=esther,
+            type=RoleType.objects.get(identifier=ROLE_TYPE_EXT_SCI),
+            orgunit=OrganizationalUnit.objects.get(name_en=OU_EUROPE_NAME_EN),
+            start_date=datetime.date.today() - datetime.timedelta(days=200),
+            end_date=datetime.date.today() - datetime.timedelta(days=100),
+            sponsor=Sponsor.objects.get(feide_id=SPONSOR_FEIDEID),
+        )
+        Identity.objects.create(
+            person=esther,
+            type=Identity.IdentityType.PASSPORT_NUMBER,
+            source=TESTDATA_SOURCE,
+            value="DK-123456789",
+            verified_at=timezone.now() - datetime.timedelta(days=205),
+        )
+        Identity.objects.create(
+            person=esther,
+            type=Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER,
+            source=TESTDATA_SOURCE,
+            value="12345678901",
+            verified_at=timezone.now() - datetime.timedelta(days=205),
+        )
+        invitation = Invitation.objects.create(
+            role=role,
+        )
+        InvitationLink.objects.create(
+            invitation=invitation,
+            expire=timezone.now() - datetime.timedelta(days=204),
+        )
+        Consent.objects.create(
+            person=esther,
+            type=ConsentType.objects.get(identifier=CONSENT_IDENT_MANDATORY),
+            consent_given_at=datetime.date.today() - datetime.timedelta(days=206),
+        )
+
+    def populate_database(self):
+        logger.info("populating db...")
+        # Add the types, sponsors and ous
+        self._add_consenttypes()
+        self._add_ous_with_identifiers()
+        self._add_roletypes()
+        self._add_sponsors()
+        # Add the four guests
+        self._add_active_person()
+        self._add_waiting_person()
+        self._add_invited_person()
+        self._add_expired_person()
+        logger.info("...done populating db")
+
+
+if __name__ == "__main__":
+    database_population = DatabasePopulation()
+    database_population.truncate_tables()
+    database_population.populate_database()
diff --git a/gregsite/settings/base.py b/gregsite/settings/base.py
index 7a618734d1a449a891d4e8078810d3064a4500e1..81e06942dd58b9fc1a355ea0bfeabf8f25148220 100644
--- a/gregsite/settings/base.py
+++ b/gregsite/settings/base.py
@@ -11,7 +11,7 @@ https://docs.djangoproject.com/en/3.2/ref/settings/
 """
 
 from pathlib import Path
-from typing import List, Literal
+from typing import List
 
 # Build paths inside the project like this: BASE_DIR / 'subdir'.
 BASE_DIR = Path(__file__).resolve().parent.parent
@@ -268,6 +268,21 @@ INTERNAL_RK_PREFIX = "no.{instance}.greg".format(instance=INSTANCE_NAME)
 
 FEIDE_SOURCE = "feide"
 
+# Rate limit settings of invite endpoint
+REST_FRAMEWORK = {
+    "DEFAULT_THROTTLE_CLASSES": [
+        "rest_framework.throttling.AnonRateThrottle",
+    ],
+    "DEFAULT_THROTTLE_RATES": {
+        "anon": "100/day",
+    },
+}
+
+
 # Used by the OU import from orgreg to distinguish the OuIdentifiers from others
 ORGREG_SOURCE = "orgreg"
 ORGREG_NAME = "orgreg_id"
+
+# Extra ids to be imported from orgreg, list of dict with source/type.
+# [{"source": "sapuio", "type": "legacy_stedkode"}]
+ORGREG_EXTRA_IDS = []
diff --git a/gregsite/settings/dev.py b/gregsite/settings/dev.py
index 0d50da5f288ab1fec646eaf68bb821e4008f9363..5cd39430464c501ad8e133dbc9581f634d02752e 100644
--- a/gregsite/settings/dev.py
+++ b/gregsite/settings/dev.py
@@ -45,6 +45,14 @@ SESSION_COOKIE_SAMESITE = "Lax"
 
 SESSION_COOKIE_AGE = 1209600  # two weeks for easy development
 
+# Disable throttling in development, uncomment CACHES to test
+CACHES = {
+    "default": {
+        "BACKEND": "django.core.cache.backends.dummy.DummyCache",
+    }
+}
+
+
 try:
     from .local import *
 except ImportError:
diff --git a/gregsite/settings/prod.py b/gregsite/settings/prod.py
index fddaf490faf58b375a52ffea9e40ed0deb7b229d..0336f7bc6af9dd96381348351c2053dc900549c7 100644
--- a/gregsite/settings/prod.py
+++ b/gregsite/settings/prod.py
@@ -27,6 +27,13 @@ ALLOWED_HOSTS = (
     else []
 )
 
+# This is the default values for CACHES, only present for clarity
+CACHES = {
+    "default": {
+        "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
+    }
+}
+
 
 try:
     from .local import *
diff --git a/gregui/api/serializers/guest.py b/gregui/api/serializers/guest.py
index 3ae182f4ca405ed2eaf77743e4845ea997b47e1a..18d18158e3e8b42d26732ef6fc4b96013e3a5b2a 100644
--- a/gregui/api/serializers/guest.py
+++ b/gregui/api/serializers/guest.py
@@ -20,6 +20,7 @@ class GuestRegisterSerializer(serializers.ModelSerializer):
     fnr = serializers.CharField(
         required=False, validators=[validate_norwegian_national_id_number]
     )
+    passport = serializers.CharField(required=False)
 
     def update(self, instance, validated_data):
         mobile_phone = validated_data.pop("mobile_phone")
@@ -41,6 +42,19 @@ class GuestRegisterSerializer(serializers.ModelSerializer):
                 Identity.IdentityType.NORWEGIAN_NATIONAL_ID_NUMBER, fnr, instance
             )
 
+        if "passport" in validated_data:
+            passport = validated_data.pop("passport")
+            if not instance.passport:
+                Identity.objects.create(
+                    person=instance,
+                    type=Identity.IdentityType.PASSPORT_NUMBER,
+                    value=passport,
+                )
+            else:
+                passport_existing = instance.passport
+                passport_existing.value = passport
+                passport_existing.save()
+
         # TODO: we only want to allow changing the name if we don't have one
         #       from a reliable source (Feide/KORR)
         # TODO Comment back in after it is decided if name updates are allowed
@@ -51,7 +65,15 @@ class GuestRegisterSerializer(serializers.ModelSerializer):
 
     class Meta:
         model = Person
-        fields = ("id", "first_name", "last_name", "email", "mobile_phone", "fnr")
+        fields = (
+            "id",
+            "first_name",
+            "last_name",
+            "email",
+            "mobile_phone",
+            "fnr",
+            "passport",
+        )
         read_only_fields = ("id",)
 
 
diff --git a/gregui/api/views/invitation.py b/gregui/api/views/invitation.py
index 17f37f6096878fc2f918f5b529b11561441221cb..bd8bc50a946e7ce8d83cb17abf63bec23e564c53 100644
--- a/gregui/api/views/invitation.py
+++ b/gregui/api/views/invitation.py
@@ -13,6 +13,7 @@ from rest_framework.mixins import UpdateModelMixin
 from rest_framework.parsers import JSONParser
 from rest_framework.permissions import AllowAny
 from rest_framework.response import Response
+from rest_framework.throttling import AnonRateThrottle
 from rest_framework.views import APIView
 
 from greg.models import Identity, InvitationLink, Person
@@ -103,6 +104,7 @@ class InvitationView(CreateAPIView, DestroyAPIView):
 class CheckInvitationView(APIView):
     authentication_classes = []
     permission_classes = [AllowAny]
+    throttle_classes = [AnonRateThrottle]
 
     def post(self, request, *args, **kwargs):
         """
diff --git a/gregui/tests/api/test_invitation.py b/gregui/tests/api/test_invitation.py
index 99b6adc0b8048978a388dbec518bc834f5f1841d..95da05946e5c5781f405d396dac5537b224fb7e3 100644
--- a/gregui/tests/api/test_invitation.py
+++ b/gregui/tests/api/test_invitation.py
@@ -220,3 +220,32 @@ def test_email_update(client, invitation_link, person_foo_data, person):
 
     person.private_email.refresh_from_db()
     assert person.private_email.value == "test2@example.com"
+
+
+@pytest.mark.django_db
+def test_register_passport(client, invitation_link, person_foo_data, person):
+    passport_information = "EN-123456789"
+    data = {"person": {"mobile_phone": "+4797543992", "passport": passport_information}}
+    url = reverse("gregui-v1:invited-info")
+
+    session = client.session
+    session["invite_id"] = str(invitation_link.uuid)
+    session.save()
+
+    assert (
+        Identity.objects.filter(
+            person__id=person.id, type=Identity.IdentityType.PASSPORT_NUMBER
+        ).count()
+        == 0
+    )
+
+    response = client.post(url, data, format="json")
+
+    assert response.status_code == status.HTTP_200_OK
+    person.refresh_from_db()
+
+    registered_passport = Identity.objects.filter(
+        person__id=person.id, type=Identity.IdentityType.PASSPORT_NUMBER
+    ).get()
+
+    assert registered_passport.value == passport_information
diff --git a/gregui/tests/api/test_invite_guest.py b/gregui/tests/api/test_invite_guest.py
index 9447535e82e55055db4bb0b9211e82ef900b5cd0..f2e7e13a3cbbe82dd3cf0fe1600f7c1fc96c8112 100644
--- a/gregui/tests/api/test_invite_guest.py
+++ b/gregui/tests/api/test_invite_guest.py
@@ -14,28 +14,30 @@ from gregui.api.views.invitation import InvitationView
 def test_invite_guest(client, user_sponsor, unit_foo, role_type_foo, mocker):
     # Mock function to avoid exception because there are no e-mail templates in the database
     mocker.patch("gregui.api.views.invitation.send_invite_mail")
+
+    test_comment = "This is a test comment"
+    contact_person_unit = "This is a test contact person"
+    role_start_date = datetime.datetime.today() + datetime.timedelta(days=1)
+    role_end_date = datetime.datetime.today() + datetime.timedelta(days=10)
+
     data = {
         "first_name": "Foo",
         "last_name": "Bar",
         "email": "test@example.com",
         "role": {
-            "start_date": (
-                datetime.datetime.today() + datetime.timedelta(days=1)
-            ).strftime("%Y-%m-%d"),
-            "end_date": (
-                datetime.datetime.today() + datetime.timedelta(days=10)
-            ).strftime("%Y-%m-%d"),
+            "start_date": (role_start_date).strftime("%Y-%m-%d"),
+            "end_date": (role_end_date).strftime("%Y-%m-%d"),
             "orgunit": unit_foo.id,
             "type": role_type_foo.id,
+            "comments": test_comment,
+            "contact_person_unit": contact_person_unit,
         },
     }
     url = reverse("gregui-v1:invitation")
 
-    all_persons = Person.objects.all()
-    assert len(all_persons) == 0
+    assert len(Person.objects.all()) == 0
 
-    factory = APIRequestFactory()
-    request = factory.post(url, data, format="json")
+    request = APIRequestFactory().post(url, data, format="json")
     force_authenticate(request, user=user_sponsor)
 
     view = InvitationView.as_view()
@@ -54,6 +56,14 @@ def test_invite_guest(client, user_sponsor, unit_foo, role_type_foo, mocker):
         value="test@example.com",
     ).exists()
 
+    role = Role.objects.filter(person__id=person.id).get()
+    assert role.orgunit == unit_foo
+    assert role.type == role_type_foo
+    assert role.start_date == role_start_date.date()
+    assert role.end_date == role_end_date.date()
+    assert role.contact_person_unit == contact_person_unit
+    assert role.comments == test_comment
+
 
 @pytest.mark.django_db
 def test_invite_cancel(