diff --git a/forums/forms.py b/forums/forms.py
index 76c774e4e7223a788676ac7af3fc969dad089cd9..7274759967491868e8333467c11cbc4c3f984e00 100644
--- a/forums/forms.py
+++ b/forums/forms.py
@@ -6,7 +6,7 @@ from django import forms
 
 from ajax_select.fields import AutoCompleteSelectField
 
-from .models import Forum, Post
+from .models import Forum, Meeting, Post
 
 
 class ForumForm(forms.ModelForm):
@@ -22,6 +22,15 @@ class ForumForm(forms.ModelForm):
         self.fields['parent_object_id'].widget = forms.HiddenInput()
 
 
+class MeetingForm(ForumForm):
+    class Meta:
+        model = Meeting
+        fields = ['name', 'slug', 'description',
+                  'publicly_visible', 'moderators',
+                  'parent_content_type', 'parent_object_id',
+                  'date_from', 'date_until', 'preamble']
+
+
 class ForumGroupPermissionsForm(forms.ModelForm):
     """
     Used for granting a specific Group access to a given Forum.
diff --git a/forums/migrations/0006_meeting.py b/forums/migrations/0006_meeting.py
new file mode 100644
index 0000000000000000000000000000000000000000..02cf93d9f53e582bd87c52e03995d939f1ef2b9c
--- /dev/null
+++ b/forums/migrations/0006_meeting.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2019-03-09 08:56
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('forums', '0005_forum_description'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='Meeting',
+            fields=[
+                ('forum', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='forums.Forum')),
+                ('date_from', models.DateField()),
+                ('date_until', models.DateField()),
+                ('preamble', models.TextField(help_text='Explanatory notes for the meeting.\nYou can use ReStructuredText, see a <a href="https://devguide.python.org/documenting/#restructuredtext-primer" target="_blank">primer on python.org</a>')),
+                ('minutes', models.TextField(blank=True, help_text='To be filled in after completion of the meeting.\nYou can use ReStructuredText, see a <a href="https://devguide.python.org/documenting/#restructuredtext-primer" target="_blank">primer on python.org</a>', null=True)),
+            ],
+            bases=('forums.forum',),
+        ),
+    ]
diff --git a/forums/models.py b/forums/models.py
index ae15f3a8e2cd5da606e193fe82e1e3d2bea22514..ef03914f29c8739bffb8fd7794356079d19560cf 100644
--- a/forums/models.py
+++ b/forums/models.py
@@ -2,6 +2,8 @@ __copyright__ = "Copyright © Stichting SciPost (SciPost Foundation)"
 __license__ = "AGPL v3"
 
 
+import datetime
+
 from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
 from django.contrib.contenttypes.models import ContentType
 from django.core.urlresolvers import reverse
@@ -92,6 +94,54 @@ class Forum(models.Model):
             return None
 
 
+class Meeting(Forum):
+    """
+    A Meeting is a Forum but with fixed start and end dates,
+    and with additional descriptor fields (preamble, minutes).
+
+    By definition, adding new Posts is allowed up to and including
+    the date specified in ``date_until``. The Meeting can however
+    be viewed in perpetuity by users who have viewing rights.
+    """
+    forum = models.OneToOneField('forums.Forum', on_delete=models.CASCADE,
+                                 parent_link=True)
+    date_from = models.DateField()
+    date_until = models.DateField()
+    preamble = models.TextField(
+        help_text=(
+            'Explanatory notes for the meeting.\n'
+            'You can use ReStructuredText, see a '
+            '<a href="https://devguide.python.org/documenting/#restructuredtext-primer" '
+            'target="_blank">primer on python.org</a>')
+        )
+    minutes = models.TextField(
+        blank=True, null=True,
+        help_text=(
+            'To be filled in after completion of the meeting.\n'
+            'You can use ReStructuredText, see a '
+            '<a href="https://devguide.python.org/documenting/#restructuredtext-primer" '
+            'target="_blank">primer on python.org</a>')
+        )
+
+    def __str__(self):
+        return '%s, [%s to %s]' % (self.forum,
+                                   self.date_from.strftime('%Y-%m-%d'),
+                                   self.date_until.strftime('%Y-%m-%d'))
+
+    @property
+    def context_color(self):
+        """If meeting is future: primary; ongoing: green; voting: orange; finished: info."""
+        today = datetime.date.today()
+        if today < self.date_from:
+            return 'primary'
+        elif today <= self.date_until:
+            return 'success'
+        elif today < self.date_until + datetime.timedelta(days=8):
+            return 'warning'
+        else:
+            return 'info'
+
+
 class Post(models.Model):
     """
     A comment, feedback, question or similar, with a specified parent object.
diff --git a/forums/templates/forums/forum_list.html b/forums/templates/forums/forum_list.html
index b4a815c4b91411c33b0cef62ce2da8b3de2fb17f..f7806ccea9ef9d01e0e5cc724bacfd711fe1f96b 100644
--- a/forums/templates/forums/forum_list.html
+++ b/forums/templates/forums/forum_list.html
@@ -21,6 +21,7 @@
     {% if perms.forums.can_add_forum %}
     <ul>
       <li><a href="{% url 'forums:forum_create' %}">Create a new Forum</a></li>
+      <li><a href="{% url 'forums:meeting_create' %}">Create a new Meeting</a></li>
     </ul>
     {% endif %}
 
@@ -28,6 +29,9 @@
       {% for forum in object_list %}
       <div class="card">
 	<div class="card-header d-flex justify-content-between">
+	  {% if forum.meeting %}
+	  <span class="badge badge-{{ forum.meeting.context_color }}">Meeting:</span>
+	  {% endif %}
 	  <a href="{{ forum.get_absolute_url }}">{{ forum }}</a>
 	  <span class="badge badge-primary badge-pill">{{ forum.nr_posts }} post{{ forum.nr_posts|pluralize }}</span>
 	</div>
diff --git a/forums/urls.py b/forums/urls.py
index 989b3229c9a40e266205309076b0b33bf23675c9..8975463c8cba2feb6e2572642b4ec6a813bdd9a8 100644
--- a/forums/urls.py
+++ b/forums/urls.py
@@ -17,6 +17,11 @@ urlpatterns = [
         views.ForumCreateView.as_view(),
         name='forum_create'
     ),
+    url(
+        r'^meeting/add/$',
+        views.MeetingCreateView.as_view(),
+        name='meeting_create'
+    ),
     url(
         r'^(?P<slug>[\w-]+)/$',
         views.ForumDetailView.as_view(),
diff --git a/forums/views.py b/forums/views.py
index 5716fbd208fa352b86d064d494e77c6993a7c409..2607f47a45a77e46c0ac9b87d927b52ade5c8166 100644
--- a/forums/views.py
+++ b/forums/views.py
@@ -20,9 +20,9 @@ from guardian.mixins import PermissionRequiredMixin
 from guardian.shortcuts import (assign_perm, remove_perm,
     get_objects_for_user, get_perms, get_users_with_perms, get_groups_with_perms)
 
-from .models import Forum, Post
+from .models import Forum, Meeting, Post
 from .forms import (ForumForm, ForumGroupPermissionsForm, ForumOrganizationPermissionsForm,
-                    PostForm)
+                    MeetingForm, PostForm)
 
 from scipost.mixins import PermissionsMixin
 
@@ -49,6 +49,11 @@ class ForumCreateView(PermissionsMixin, CreateView):
         return initial
 
 
+class MeetingCreateView(ForumCreateView):
+    model = Meeting
+    form_class = MeetingForm
+
+
 class ForumUpdateView(PermissionRequiredMixin, UpdateView):
     permission_required = 'forums.update_forum'
     model = Forum