diff --git a/gracedb/forms.py b/gracedb/forms.py
index 3e51169d61bb01878c6031b998fe686a42d22933..ea9af86e1e7b22988b6c7f0c935641b62333a61b 100644
--- a/gracedb/forms.py
+++ b/gracedb/forms.py
@@ -57,6 +57,11 @@ class CreateEventForm(forms.Form):
     labels = forms.CharField(required=False)
     #type = forms.ChoiceField(choices=typeChoices)
 
+    # Offline boolean. required=False means that if the user
+    # doesn't provide a value, we use the default defined in models.py.
+    # This ensures backwards-compatibility for client versions which
+    # don't specify this parameter.
+    offline = forms.BooleanField(required=False)
 
 class EventSearchForm(forms.Form):
     groupChoices = [("","")]+[(g.name, g.name) for g in Group.objects.all()]
diff --git a/gracedb/migrations/0021_event_offline.py b/gracedb/migrations/0021_event_offline.py
new file mode 100644
index 0000000000000000000000000000000000000000..e11dcae5d26649892097f20388d4978d3d87a383
--- /dev/null
+++ b/gracedb/migrations/0021_event_offline.py
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('gracedb', '0020_fix_lib_perms'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='event',
+            name='offline',
+            field=models.BooleanField(default=False),
+        ),
+    ]
diff --git a/gracedb/models.py b/gracedb/models.py
index 96324b3d5be6d9881df7050b439586d51bf10bd3..f7ffc334730f279a3f9a46be31f223110afada73 100644
--- a/gracedb/models.py
+++ b/gracedb/models.py
@@ -135,6 +135,13 @@ class Event(models.Model):
     # searches quite considerably.
     perms = models.TextField(null=True)
 
+    # Boolean which determines whether the event was submitted by an offline
+    # analysis (True) or an online/low-latency analysis (False). Because this
+    # is being implemented during a run (O2), we use a default value of False
+    # so as to ensure backwards-compatibility; i.e., all events treated as
+    # "online" by default.
+    offline = models.BooleanField(default=False)
+
     class Meta:
         ordering = ["-id"]
 
diff --git a/gracedb/view_logic.py b/gracedb/view_logic.py
index ee77c9fd81b941da1a90bab69531ca81d923aa0a..86674a4d0f3998cd3633bbf2d7ea482ed9f71120 100644
--- a/gracedb/view_logic.py
+++ b/gracedb/view_logic.py
@@ -45,6 +45,7 @@ def _createEventFromForm(request, form):
         pipeline = Pipeline.objects.get(name=form.cleaned_data['pipeline'])
         search_name = form.cleaned_data['search']
         label_str = form.cleaned_data['labels']
+        offline = form.cleaned_data['offline']
         if search_name:
             search = Search.objects.get(name=form.cleaned_data['search'])
         else:
@@ -67,6 +68,7 @@ def _createEventFromForm(request, form):
         event.group = group
         event.pipeline = pipeline
         event.search = search
+        event.offline = offline
 
         # If the event is an injection, look for certain attributes in the POST data.
         # These attributes are unfortunately not found in the SimInspiralTable
diff --git a/gracedb/view_utils.py b/gracedb/view_utils.py
index b1b74e3ec359c6899051442d59aed5e18a2a7691..38f9828b61c98fdce94d68a51fe56de60ecda481 100644
--- a/gracedb/view_utils.py
+++ b/gracedb/view_utils.py
@@ -134,6 +134,7 @@ def eventToDict(event, columns=None, request=None):
     rv['gpstime'] = event.gpstime
     rv['instruments'] = event.instruments
     rv['nevents'] = event.nevents
+    rv['offline'] = event.offline
 
     far_is_upper_limit = False
     display_far = event.far
diff --git a/templates/gracedb/event_detail.html b/templates/gracedb/event_detail.html
index 4532358e1f160ec447264c8bf91406a81fc85b1a..e1d7251ce635cdda5c68db4c5a96c0fe154495d2 100644
--- a/templates/gracedb/event_detail.html
+++ b/templates/gracedb/event_detail.html
@@ -119,6 +119,11 @@
     </div>
 {% endif %}
 
+{% if object.offline %}
+<div style="text-align: center;">
+    <h2 style="color: red;">OFFLINE EVENT</h2>
+</div>
+{% endif %}
 
 <!-- Here is a section for the EM advocate signoffs. -->
 <!-- XXX So much ugliness here. Is there a way to do this with the JS? -->