diff --git a/infipoint/apps/infinita/migrations/0001_initial.py b/infipoint/apps/infinita/migrations/0001_initial.py
new file mode 100644
index 0000000000000000000000000000000000000000..d417cedf725486e347145e7d4c55d988bcd865e0
--- /dev/null
+++ b/infipoint/apps/infinita/migrations/0001_initial.py
@@ -0,0 +1,35 @@
+# Generated by Django 4.2.9 on 2024-01-20 14:52
+
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+    initial = True
+
+    dependencies = [
+        ("resint", "0010_drop_site"),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name="Announcements",
+            fields=[
+                (
+                    "livedocument_ptr",
+                    models.OneToOneField(
+                        auto_created=True,
+                        on_delete=django.db.models.deletion.CASCADE,
+                        parent_link=True,
+                        primary_key=True,
+                        serialize=False,
+                        to="resint.livedocument",
+                    ),
+                ),
+            ],
+            options={
+                "abstract": False,
+            },
+            bases=("resint.livedocument",),
+        ),
+    ]
diff --git a/infipoint/apps/infinita/models/documents.py b/infipoint/apps/infinita/models/documents.py
new file mode 100644
index 0000000000000000000000000000000000000000..ceca3705eb0a1aa603b31205df15df6d90d55f0d
--- /dev/null
+++ b/infipoint/apps/infinita/models/documents.py
@@ -0,0 +1,28 @@
+from typing import Any, Dict
+
+from django.db.models.signals import post_save
+from django.dispatch import receiver
+
+from aleksis.apps.resint.models import LiveDocument
+from aleksis.core.models import Announcement
+
+
+class Announcements(LiveDocument):
+    """Model for configuring automatically updated announcements PDF."""
+
+    template = "infinita/announcements.html"
+
+    def get_context_data(self) -> Dict[str, Any]:
+        """Get context data for generating the substitutions PDF."""
+        from aleksis.core.models import Announcement  # noqa
+
+        context = {"announcements": Announcement.objects.on_date()}
+
+        return context
+
+
+@receiver(post_save, sender=Announcement)
+def announcements_signal_receiver(sender, instance, **kwargs):
+    if Announcement.objects.filter(pk=instance.pk).on_date():
+        for document in Announcements.objects.all():
+            document.update()
diff --git a/infipoint/apps/infinita/templates/infinita/announcements.html b/infipoint/apps/infinita/templates/infinita/announcements.html
new file mode 100644
index 0000000000000000000000000000000000000000..1a97bdfe8c37f1c3d13b44acf186b614d32661d7
--- /dev/null
+++ b/infipoint/apps/infinita/templates/infinita/announcements.html
@@ -0,0 +1,17 @@
+{# -*- engine:django -*- #}
+
+{% extends 'core/base_print.html' %}
+
+{% load i18n static %}
+
+{% block extra_head %}
+  <link rel="stylesheet" href="{% static 'css/chronos/timetable.css' %}">
+{% endblock %}
+
+{% block browser_title %}{% blocktrans %}Print: Announcements{% endblocktrans %}{% endblock %}
+{% block page_title %}{% blocktrans %}Announcements{% endblocktrans %}{% endblock %}
+
+
+{% block content %}
+{% include "core/partials/announcements.html" with announcements=announcements %}
+{% endblock %}