diff --git a/organizations/constants.py b/organizations/constants.py
index ba57d4e4412b2f6a39cc5edb52e35d091bbbb04a..8b581b880bfa77a336aafde1ab6fe32f290fda66 100644
--- a/organizations/constants.py
+++ b/organizations/constants.py
@@ -64,6 +64,24 @@ ORGANIZATION_STATUSES = (
     (ORGSTATUS_OBSOLETE, 'Obsolete'),
 )
 
+
+ORGANIZATION_EVENT_REQUESTED = 'requested'
+ORGANIZATION_EVENT_COMMENT = 'comment'
+ORGANIZATION_EVENT_EMAIL_SENT = 'email_sent'
+ORGANIZATION_EVENT_INITIATE_NEGOTIATION = 'negotiating'
+ORGANIZATION_EVENT_MARKED_AS_UNINTERESTED = 'marked_as_uninterested'
+ORGANIZATION_EVENT_PROMOTED = 'promoted'
+ORGANIZATION_STATUS_UPDATED = 'status_updated'
+ORGANIZATION_EVENTS = (
+    (ORGANIZATION_EVENT_REQUESTED, 'Requested (from online form)'),
+    (ORGANIZATION_EVENT_COMMENT, 'Comment added'),
+    (ORGANIZATION_EVENT_EMAIL_SENT, 'Email sent'),
+    (ORGANIZATION_EVENT_INITIATE_NEGOTIATION, 'Initiated negotiation'),
+    (ORGANIZATION_EVENT_MARKED_AS_UNINTERESTED, 'Marked as uninterested'),
+    (ORGANIZATION_EVENT_PROMOTED, 'Promoted to Sponsor'),
+    (ORGANIZATION_STATUS_UPDATED, 'Status updated'),
+)
+
 ROLE_GENERAL = 'gen'
 ROLE_TECH = 'tech'
 ROLE_FIN = 'fin'
diff --git a/organizations/migrations/0004_organizationevent.py b/organizations/migrations/0004_organizationevent.py
new file mode 100644
index 0000000000000000000000000000000000000000..08f127935ca354b8056889128274a61e3b07074a
--- /dev/null
+++ b/organizations/migrations/0004_organizationevent.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.4 on 2019-02-19 07:52
+from __future__ import unicode_literals
+
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+        ('organizations', '0003_contact_contactperson_contactrole'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='OrganizationEvent',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('event', models.CharField(choices=[('requested', 'Requested (from online form)'), ('comment', 'Comment added'), ('email_sent', 'Email sent'), ('negotiating', 'Initiated negotiation'), ('marked_as_uninterested', 'Marked as uninterested'), ('promoted', 'Promoted to Sponsor'), ('status_updated', 'Status updated')], max_length=64)),
+                ('comments', models.TextField(blank=True)),
+                ('noted_on', models.DateTimeField(auto_now_add=True)),
+                ('noted_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+                ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='organizations.Organization')),
+            ],
+        ),
+    ]
diff --git a/organizations/models.py b/organizations/models.py
index fc5b30655b19fd9ffb38a9fd0f18b4f40cdf62d3..6fbdd9bc78c9a3df7146710f065daf08fa5b7d64 100644
--- a/organizations/models.py
+++ b/organizations/models.py
@@ -17,8 +17,7 @@ from django.urls import reverse
 from django_countries.fields import CountryField
 
 from .constants import ORGANIZATION_TYPES, ORGTYPE_PRIVATE_BENEFACTOR,\
-    ORGANIZATION_STATUSES, ORGSTATUS_ACTIVE,\
-    ROLE_KINDS
+    ORGANIZATION_STATUSES, ORGSTATUS_ACTIVE, ORGANIZATION_EVENTS, ROLE_KINDS
 from .managers import OrganizationQuerySet
 
 from scipost.constants import TITLE_CHOICES
@@ -185,6 +184,25 @@ class Organization(models.Model):
 
 
 
+###################################
+# Events related to Organizations #
+###################################
+
+class OrganizationEvent(models.Model):
+    """
+    Documents an event related to an Organization.
+    """
+    organization = models.ForeignKey('organizations.Organization', on_delete=models.CASCADE)
+    event = models.CharField(max_length=64, choices=ORGANIZATION_EVENTS)
+    comments = models.TextField(blank=True)
+    noted_on = models.DateTimeField(auto_now_add=True)
+    noted_by = models.ForeignKey(User, on_delete=models.CASCADE)
+
+    def __str__(self):
+        return '%s: %s' % (str(self.organization), self.get_event_display())
+
+
+
 ####################################
 # Contact persons, users and roles #
 ####################################
diff --git a/partners/models.py b/partners/models.py
index 19ee9d0d69e44ca7de17b645e20af6e01dc1931e..39ea44207f08497ffe3f2da3e2ac2f5c086814d5 100644
--- a/partners/models.py
+++ b/partners/models.py
@@ -47,6 +47,7 @@ now = timezone.now()
 # Prospective Partners #
 ########################
 
+# TODO: to be deleted, use Organization instead
 class ProspectivePartner(models.Model):
     """A prospect Partner is a Partner without explicit contract with SciPost yet."""
 
@@ -102,6 +103,7 @@ class ProspectiveContact(models.Model):
         return "%s %s %s" % (self.get_title_display(), self.first_name, self.last_name)
 
 
+# TODO: delete, superseded by OrganizationEvent
 class ProspectivePartnerEvent(models.Model):
     prospartner = models.ForeignKey('partners.ProspectivePartner', on_delete=models.CASCADE)
     event = models.CharField(max_length=64, choices=PROSPECTIVE_PARTNER_EVENTS)
@@ -204,6 +206,7 @@ class Contact(models.Model):
         return ', '.join([choices[value] for index, value in enumerate(self.kind)])
 
 
+# TODO: delete, use Organizations instead
 class Partner(models.Model):
     """
     Supporting Partners.
@@ -234,6 +237,7 @@ class Partner(models.Model):
         raise NotImplemented
 
 
+# TODO: delete, superseded by OrganizationEvent
 class PartnerEvent(models.Model):
     partner = models.ForeignKey('partners.Partner', on_delete=models.CASCADE,
                                 related_name='events')
@@ -246,6 +250,7 @@ class PartnerEvent(models.Model):
         return '%s: %s' % (str(self.partner), self.get_event_display())
 
 
+# TODO: delete, use finances.Subsidy instead
 class MembershipAgreement(models.Model):
     """
     Agreement for membership of the Supporting Partners Board.
@@ -271,6 +276,7 @@ class MembershipAgreement(models.Model):
         return reverse('partners:agreement_details', args=(self.id,))
 
 
+# TODO: delete, use finances.SubsidyAttachment instead
 class PartnersAttachment(models.Model):
     """
     An Attachment which can (in the future) be related to a Partner, Contact, MembershipAgreement,