diff --git a/apimail/admin.py b/apimail/admin.py
index c9db40e95a0b6cd8c460d50c71f5adce6213e51a..6ea48c9d3e78691675e90ac96297cc8bfc46672b 100644
--- a/apimail/admin.py
+++ b/apimail/admin.py
@@ -5,6 +5,7 @@ __license__ = "AGPL v3"
 from django.contrib import admin
 
 from .models import (
+    Domain,
     EmailAccount, EmailAccountAccess,
     AttachmentFile,
     ComposedMessage, ComposedMessageAPIResponse,
@@ -13,6 +14,9 @@ from .models import (
     UserTag)
 
 
+admin.site.register(Domain)
+
+
 class EmailAccountAccessInline(admin.StackedInline):
     model = EmailAccountAccess
     extra = 0
diff --git a/apimail/migrations/0021_auto_20201017_1016.py b/apimail/migrations/0021_auto_20201017_1016.py
new file mode 100644
index 0000000000000000000000000000000000000000..01efa3ea1549c47d830d495cb25ac7be581989da
--- /dev/null
+++ b/apimail/migrations/0021_auto_20201017_1016.py
@@ -0,0 +1,30 @@
+# Generated by Django 2.2.16 on 2020-10-17 08:16
+
+import apimail.validators
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('apimail', '0020_auto_20200214_1159'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Domain',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('name', models.CharField(max_length=100, unique=True, validators=[apimail.validators._simple_domain_name_validator])),
+            ],
+            options={
+                'ordering': ('name',),
+            },
+        ),
+        migrations.AddField(
+            model_name='emailaccount',
+            name='domain',
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='email_accounts', to='apimail.Domain'),
+        ),
+    ]
diff --git a/apimail/migrations/0022_auto_20201017_1018.py b/apimail/migrations/0022_auto_20201017_1018.py
new file mode 100644
index 0000000000000000000000000000000000000000..3230748f828d7b533e809795d1f4515d7e3e0383
--- /dev/null
+++ b/apimail/migrations/0022_auto_20201017_1018.py
@@ -0,0 +1,19 @@
+# Generated by Django 2.2.16 on 2020-10-17 08:18
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('apimail', '0021_auto_20201017_1016'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='emailaccount',
+            name='domain',
+            field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='email_accounts', to='apimail.Domain'),
+        ),
+    ]
diff --git a/apimail/models/__init__.py b/apimail/models/__init__.py
index 4ef781dbb2148bb2a03bf4a46e32342c3422c54a..4f8395d53ee2ec0bc63bbef7012e0b5bfe279768 100644
--- a/apimail/models/__init__.py
+++ b/apimail/models/__init__.py
@@ -8,6 +8,8 @@ from .attachment import AttachmentFile
 
 from .composed_message import ComposedMessage, ComposedMessageAPIResponse
 
+from .domain import Domain
+
 from .event import Event
 
 from .stored_message import StoredMessage
diff --git a/apimail/models/account.py b/apimail/models/account.py
index c0537002de32642e3b76e77a7a4134fc05fa8a5d..fb59da3d1db1ef86471d81717800aad1dcf081f6 100644
--- a/apimail/models/account.py
+++ b/apimail/models/account.py
@@ -3,6 +3,7 @@ __license__ = "AGPL v3"
 
 
 from django.conf import settings
+from django.core.exceptions import ValidationError
 from django.db import models
 
 from ..managers import EmailAccountAccessQuerySet
@@ -14,6 +15,11 @@ class EmailAccount(models.Model):
 
     Access is specified on a per-user basis through the related EmailAccountAccess model.
     """
+    domain = models.ForeignKey(
+        'apimail.Domain',
+        related_name='email_accounts',
+        on_delete=models.CASCADE
+    )
     name = models.CharField(max_length=256)
     email = models.EmailField(unique=True)
     description = models.TextField()
@@ -24,6 +30,10 @@ class EmailAccount(models.Model):
     def __str__(self):
         return('%s <%s>' % (self.name, self.email))
 
+    def clean(self):
+        if self.email.rpartition('@')[2] != self.domain.name:
+            raise ValidationError("Email domain does not match domain name.")
+
 
 class EmailAccountAccess(models.Model):
     """
diff --git a/apimail/models/domain.py b/apimail/models/domain.py
new file mode 100644
index 0000000000000000000000000000000000000000..92184bd46732ccf44aa275285e1a4919dffc8155
--- /dev/null
+++ b/apimail/models/domain.py
@@ -0,0 +1,24 @@
+_copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
+__license__ = "AGPL v3"
+
+
+from django.db import models
+
+from ..validators import _simple_domain_name_validator
+
+
+class Domain(models.Model):
+    """
+    Domain name information.
+    """
+    name = models.CharField(
+        max_length=100,
+        validators=[_simple_domain_name_validator],
+        unique=True,
+    )
+
+    class Meta:
+        ordering = ('name',)
+
+    def __str__(self):
+        return self.name
diff --git a/apimail/validators.py b/apimail/validators.py
index 2c5581249aedefa5434ef6b9b0d4b3b1d616872b..8bd1602f02242c48f9f0d19f23a61fa60d619724 100644
--- a/apimail/validators.py
+++ b/apimail/validators.py
@@ -2,11 +2,27 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
 
+import string
+
 from django.conf import settings
 from django.core.exceptions import ValidationError
 from django.template.defaultfilters import filesizeformat
 
 
+def _simple_domain_name_validator(value):
+    """
+    Validate that the given value contains no whitespaces to prevent common typos.
+
+    Taken from django.contrib.sites.models
+    """
+    checks = ((s in value) for s in string.whitespace)
+    if any(checks):
+        raise ValidationError(
+            "The domain name cannot contain any spaces or tabs.",
+            code='invalid',
+        )
+
+
 def validate_max_email_attachment_file_size(value):
     if value.size > int(settings.MAX_EMAIL_ATTACHMENT_FILE_SIZE):
         raise ValidationError(