diff --git a/src/openklant/components/klantinteracties/migrations/0003_betrokkene.py b/src/openklant/components/klantinteracties/migrations/0003_betrokkene.py
new file mode 100644
index 00000000..1e16ddbf
--- /dev/null
+++ b/src/openklant/components/klantinteracties/migrations/0003_betrokkene.py
@@ -0,0 +1,199 @@
+# Generated by Django 3.2.18 on 2023-10-11 10:26
+
+import django.core.validators
+from django.db import migrations, models
+import django.db.models.deletion
+import uuid
+
+
+class Migration(migrations.Migration):
+    dependencies = [
+        ("klantinteracties", "0002_klantcontact"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="Betrokkene",
+            fields=[
+                (
+                    "id",
+                    models.UUIDField(
+                        default=uuid.uuid4,
+                        help_text="Unieke (technische) identificatiecode van de betrokkene bij klantcontact.",
+                        primary_key=True,
+                        serialize=False,
+                        unique=True,
+                    ),
+                ),
+                (
+                    "rol",
+                    models.CharField(
+                        choices=[
+                            ("vertegenwoordiger", "Vertegenwoordiger"),
+                            ("klant", "Klant"),
+                        ],
+                        help_text="Rol die de betrokkene bij klantcontact tijdens dat contact vervulde.",
+                        max_length=17,
+                        verbose_name="Rol",
+                    ),
+                ),
+                (
+                    "organisatienaam",
+                    models.CharField(
+                        blank=True,
+                        help_text="Naam van de organisatie waarmee de betrokkene bij klantcontact een relatie had.",
+                        max_length=200,
+                        verbose_name="Organisatienaam",
+                    ),
+                ),
+                (
+                    "contactnaam_voorletters",
+                    models.CharField(
+                        help_text="Een afkorting van de voornamen. Meestal de beginletter, maar in sommige gevallen de beginletter gecombineerd met de tweede letter van een voornaam.",
+                        max_length=6,
+                        verbose_name="Voorletters",
+                    ),
+                ),
+                (
+                    "contactnaam_voornaam",
+                    models.CharField(
+                        blank=True,
+                        help_text="De voornaam die de persoon wil gebruiken tijdens communicatie met de gemeente.",
+                        max_length=200,
+                        verbose_name="Voornaam",
+                    ),
+                ),
+                (
+                    "contactnaam_voorvoegsel_achternaam",
+                    models.CharField(
+                        blank=True,
+                        help_text="Een eventueel voorvoegsel dat hoort bij de achternaam die de persoon wil gebruiken tijdens communicatie met de gemeente.",
+                        max_length=10,
+                        verbose_name="Voorvoegsel achternaam",
+                    ),
+                ),
+                (
+                    "contactnaam_achternaam",
+                    models.CharField(
+                        blank=True,
+                        help_text="Een achternaam die de persoon wil gebruiken tijdens communicatie met de gemeente.",
+                        max_length=200,
+                        verbose_name="Achternaam",
+                    ),
+                ),
+                (
+                    "correspondentieadres_nummeraanduiding_id",
+                    models.UUIDField(
+                        default=uuid.uuid4,
+                        help_text="Identificatie van het adres bij de Basisregistratie Adressen en Gebouwen.",
+                        unique=True,
+                    ),
+                ),
+                (
+                    "correspondentieadres_adresregel1",
+                    models.CharField(
+                        blank=True,
+                        help_text="Eerste deel van het adres dat niet voorkomt in de Basisregistratie Adressen en Gebouwen.",
+                        max_length=80,
+                        verbose_name="Adresregel 1",
+                    ),
+                ),
+                (
+                    "correspondentieadres_adresregel2",
+                    models.CharField(
+                        blank=True,
+                        help_text="Tweede deel van het adres dat niet voorkomt in de Basisregistratie Adressen en Gebouwen.",
+                        max_length=80,
+                        verbose_name="Adresregel 2",
+                    ),
+                ),
+                (
+                    "correspondentieadres_adresregel3",
+                    models.CharField(
+                        blank=True,
+                        help_text="Derde van het adres dat niet voorkomt in de Basisregistratie Adressen en Gebouwen.",
+                        max_length=80,
+                        verbose_name="Adresregel 3",
+                    ),
+                ),
+                (
+                    "correspondentieadres_land",
+                    models.IntegerField(
+                        blank=True,
+                        help_text="Een code, opgenomen in Tabel 34, Landentabel, die het land (buiten Nederland) aangeeft alwaar de ingeschrevene verblijft.",
+                        validators=[django.core.validators.MaxValueValidator(9999)],
+                        verbose_name="Land",
+                    ),
+                ),
+                (
+                    "bezoekadres_nummeraanduiding_id",
+                    models.UUIDField(
+                        default=uuid.uuid4,
+                        help_text="Identificatie van het adres bij de Basisregistratie Adressen en Gebouwen.",
+                        unique=True,
+                    ),
+                ),
+                (
+                    "bezoekadres_adresregel1",
+                    models.CharField(
+                        blank=True,
+                        help_text="Eerste deel van het adres dat niet voorkomt in de Basisregistratie Adressen en Gebouwen.",
+                        max_length=80,
+                        verbose_name="Adresregel 1",
+                    ),
+                ),
+                (
+                    "bezoekadres_adresregel2",
+                    models.CharField(
+                        blank=True,
+                        help_text="Tweede deel van het adres dat niet voorkomt in de Basisregistratie Adressen en Gebouwen.",
+                        max_length=80,
+                        verbose_name="Adresregel 2",
+                    ),
+                ),
+                (
+                    "bezoekadres_adresregel3",
+                    models.CharField(
+                        blank=True,
+                        help_text="Derde deel van het adres dat niet voorkomt in de Basisregistratie Adressen en Gebouwen.",
+                        max_length=80,
+                        verbose_name="Adresregel 3",
+                    ),
+                ),
+                (
+                    "bezoekadres_land",
+                    models.IntegerField(
+                        blank=True,
+                        help_text="Een code, opgenomen in Tabel 34, Landentabel, die het land (buiten Nederland) aangeeft alwaar de ingeschrevene verblijft.",
+                        validators=[django.core.validators.MaxValueValidator(9999)],
+                        verbose_name="Land",
+                    ),
+                ),
+                (
+                    "klantcontact",
+                    models.ForeignKey(
+                        help_text="'Klantcontact' had 'Betrokkene bij klantcontact'",
+                        on_delete=django.db.models.deletion.CASCADE,
+                        related_name="betrokkene",
+                        to="klantinteracties.klantcontact",
+                        verbose_name="Klantcontact",
+                    ),
+                ),
+            ],
+            options={
+                "verbose_name": "betrokkene bij klantcontact",
+            },
+        ),
+        migrations.AddField(
+            model_name="partij",
+            name="betrokkene",
+            field=models.ForeignKey(
+                help_text="'Betrokkene bij klantcontact' was 'Partij'",
+                null=True,
+                on_delete=django.db.models.deletion.CASCADE,
+                related_name="partijen",
+                to="klantinteracties.betrokkene",
+                verbose_name="Betrokkene",
+            ),
+        ),
+    ]
diff --git a/src/openklant/components/klantinteracties/models/klantcontacten.py b/src/openklant/components/klantinteracties/models/klantcontacten.py
index 80bae6d1..27476d28 100644
--- a/src/openklant/components/klantinteracties/models/klantcontacten.py
+++ b/src/openklant/components/klantinteracties/models/klantcontacten.py
@@ -4,7 +4,9 @@
 from django.db import models
 from django.utils.translation import gettext_lazy as _
 
-from .constants import Initiator
+from vng_api_common.descriptors import GegevensGroepType
+
+from .constants import Initiator, Klantcontrol
 
 
 class Klantcontact(models.Model):
@@ -109,3 +111,195 @@ class Meta:
 
         def __str__(self) -> str:
             return self.nummer
+
+
+class Betrokkene(models.Model):
+    id = models.UUIDField(
+        primary_key=True,
+        unique=True,
+        default=uuid.uuid4,
+        max_length=40,
+        help_text=_(
+            "Unieke (technische) identificatiecode van de betrokkene bij klantcontact."
+        ),
+    )
+    klantcontact = models.ForeignKey(
+        Klantcontact,
+        on_delete=models.CASCADE,
+        verbose_name=_("Klantcontact"),
+        related_name="betrokkene",
+        help_text=_("'Klantcontact' had 'Betrokkene bij klantcontact'"),
+        null=False,
+    )
+    # TODO: Add fk to Digital adres
+    rol = models.CharField(
+        _("Rol"),
+        help_text=_(
+            "Rol die de betrokkene bij klantcontact tijdens dat contact vervulde."
+        ),
+        choices=Klantcontrol.choices,
+        max_length=17,
+        blank=False,
+    )
+    organisatienaam = models.CharField(
+        _("Organisatienaam"),
+        help_text=_(
+            "Naam van de organisatie waarmee de betrokkene bij klantcontact een relatie had."
+        ),
+        max_length=200,
+        blank=True,
+    )
+
+    # Contactnaam model fields:
+    # TODO: check if the max length is correct
+    contactnaam_voorletters = models.CharField(
+        _("Voorletters"),
+        help_text=_(
+            "Een afkorting van de voornamen. Meestal de beginletter, maar in sommige gevallen "
+            "de beginletter gecombineerd met de tweede letter van een voornaam."
+        ),
+        max_length=6,
+        blank=False,
+    )
+    contactnaam_voornaam = models.CharField(
+        _("Voornaam"),
+        help_text=_(
+            "De voornaam die de persoon wil gebruiken tijdens communicatie met de gemeente."
+        ),
+        max_length=200,
+        blank=True,
+    )
+    contactnaam_voorvoegsel_achternaam = models.CharField(
+        _("Voorvoegsel achternaam"),
+        help_text=_(
+            "Een eventueel voorvoegsel dat hoort bij de achternaam die de persoon "
+            "wil gebruiken tijdens communicatie met de gemeente."
+        ),
+        max_length=10,
+        blank=True,
+    )
+    contactnaam_achternaam = models.CharField(
+        _("Achternaam"),
+        help_text=_(
+            "Een achternaam die de persoon wil gebruiken tijdens communicatie met de gemeente."
+        ),
+        max_length=200,
+        blank=True,
+    )
+
+    # Correspondentieadres model fields:
+    correspondentieadres_nummeraanduiding_id = models.UUIDField(
+        default=uuid.uuid4,
+        unique=True,
+        max_length=40,
+        help_text=_(
+            "Identificatie van het adres bij de Basisregistratie Adressen en Gebouwen."
+        ),
+    )
+    correspondentieadres_adresregel1 = models.CharField(
+        _("Adresregel 1"),
+        help_text=_(
+            "Eerste deel van het adres dat niet voorkomt in de Basisregistratie Adressen en Gebouwen."
+        ),
+        max_length=80,
+        blank=True,
+    )
+    correspondentieadres_adresregel2 = models.CharField(
+        _("Adresregel 2"),
+        help_text=_(
+            "Tweede deel van het adres dat niet voorkomt in de Basisregistratie Adressen en Gebouwen."
+        ),
+        max_length=80,
+        blank=True,
+    )
+    correspondentieadres_adresregel3 = models.CharField(
+        _("Adresregel 3"),
+        help_text=_(
+            "Derde van het adres dat niet voorkomt in de Basisregistratie Adressen en Gebouwen."
+        ),
+        max_length=80,
+        blank=True,
+    )
+    correspondentieadres_land = models.IntegerField(
+        _("Land"),
+        help_text=_(
+            "Een code, opgenomen in Tabel 34, Landentabel, die het land (buiten Nederland) "
+            "aangeeft alwaar de ingeschrevene verblijft."
+        ),
+        validators=[MaxValueValidator(9999)],
+        blank=True,
+    )
+
+    # Bezoekadres model fields:
+    bezoekadres_nummeraanduiding_id = models.UUIDField(
+        default=uuid.uuid4,
+        unique=True,
+        max_length=40,
+        help_text=_(
+            "Identificatie van het adres bij de Basisregistratie Adressen en Gebouwen."
+        ),
+    )
+    bezoekadres_adresregel1 = models.CharField(
+        _("Adresregel 1"),
+        help_text=_(
+            "Eerste deel van het adres dat niet voorkomt in de Basisregistratie Adressen en Gebouwen."
+        ),
+        max_length=80,
+        blank=True,
+    )
+    bezoekadres_adresregel2 = models.CharField(
+        _("Adresregel 2"),
+        help_text=_(
+            "Tweede deel van het adres dat niet voorkomt in de Basisregistratie Adressen en Gebouwen."
+        ),
+        max_length=80,
+        blank=True,
+    )
+    bezoekadres_adresregel3 = models.CharField(
+        _("Adresregel 3"),
+        help_text=_(
+            "Derde deel van het adres dat niet voorkomt in de Basisregistratie Adressen en Gebouwen."
+        ),
+        max_length=80,
+        blank=True,
+    )
+    bezoekadres_land = models.IntegerField(
+        _("Land"),
+        help_text=_(
+            "Een code, opgenomen in Tabel 34, Landentabel, die het land (buiten Nederland) "
+            "aangeeft alwaar de ingeschrevene verblijft."
+        ),
+        validators=[MaxValueValidator(9999)],
+        blank=True,
+    )
+
+    # Group types:
+    Contactnaam = GegevensGroepType(
+        {
+            "voorletters": contactnaam_voorletters,
+            "voornaam": contactnaam_voornaam,
+            "voorvoegsel achternaam": contactnaam_voorvoegsel_achternaam,
+            "achternaam": contactnaam_achternaam,
+        }
+    )
+    correspondentieadres = GegevensGroepType(
+        {
+            "nummeraanduiding id": correspondentieadres_nummeraanduiding_id,
+            "adresregel 1": correspondentieadres_adresregel1,
+            "adresregel 2": correspondentieadres_adresregel2,
+            "adresregel 3": correspondentieadres_adresregel3,
+            "land": correspondentieadres_land,
+        },
+    )
+    bezoekadres = GegevensGroepType(
+        {
+            "nummeraanduiding id": bezoekadres_nummeraanduiding_id,
+            "adresregel 1": bezoekadres_adresregel1,
+            "adresregel 2": bezoekadres_adresregel2,
+            "adresregel 3": bezoekadres_adresregel3,
+            "land": bezoekadres_land,
+        }
+    )
+
+    class Meta:
+        verbose_name = "betrokkene bij klantcontact"
diff --git a/src/openklant/components/klantinteracties/models/partijen.py b/src/openklant/components/klantinteracties/models/partijen.py
index 3525dc5d..60efaa40 100644
--- a/src/openklant/components/klantinteracties/models/partijen.py
+++ b/src/openklant/components/klantinteracties/models/partijen.py
@@ -7,6 +7,7 @@
 from vng_api_common.descriptors import GegevensGroepType
 
 from .constants import SoortPartij
+from .klantcontacten import Betrokkene
 
 
 class Partij(models.Model):
@@ -19,6 +20,14 @@ class Partij(models.Model):
             "Unieke (technische) identificatiecode van de betrokkene bij klantcontact."
         ),
     )
+    betrokkene = models.ForeignKey(
+        Betrokkene,
+        on_delete=models.CASCADE,
+        verbose_name=_("Betrokkene"),
+        related_name="partijen",
+        help_text=_("'Betrokkene bij klantcontact' was 'Partij'"),
+        null=True,
+    )
     nummer = models.PositiveIntegerField(
         _("Nummer"),
         help_text=_(
@@ -218,6 +227,8 @@ class Persoon(models.Model):
         on_delete=models.CASCADE,
         related_name="persoon",
     )
+
+    # Contactnaam model fields:
     # TODO: check if the max length is correct
     contactnaam_voorletters = models.CharField(
         _("Voorletters"),
@@ -254,6 +265,7 @@ class Persoon(models.Model):
         blank=True,
     )
 
+    # Group types:
     Contactnaam = GegevensGroepType(
         {
             "voorletters": contactnaam_voorletters,
@@ -285,6 +297,8 @@ class Contactpersoon(models.Model):
         help_text=_("De organisatie waar een contactpersoon voor werkt."),
         null=True,
     )
+
+    # Contactnaam model fields:
     # TODO: check if the max length is correct
     contactnaam_voorletters = models.CharField(
         _("Voorletters"),
@@ -321,6 +335,7 @@ class Contactpersoon(models.Model):
         blank=True,
     )
 
+    # Group types:
     Contactnaam = GegevensGroepType(
         {
             "voorletters": contactnaam_voorletters,