diff --git a/gracedb/api/v1/events/views.py b/gracedb/api/v1/events/views.py
index 14c7e9444da7852eb1b985d55ea101d64f37f8cf..c7ead4b47379271f6bd92af025e6955eb1e82d9e 100644
--- a/gracedb/api/v1/events/views.py
+++ b/gracedb/api/v1/events/views.py
@@ -1599,6 +1599,10 @@ class VOEventList(APIView):
         CoincComment = request.data.get('CoincComment', None)
         ProbHasNS = request.data.get('ProbHasNS', None)
         ProbHasRemnant = request.data.get('ProbHasRemnant', None)
+        BNS = request.data.get('BNS', None)
+        NSBH = request.data.get('NSBH', None)
+        BBH = request.data.get('BBH', None)
+        Terrestrial = request.data.get('Terrestrial', None)
 
         if (skymap_filename and not skymap_type) or (skymap_type and not skymap_filename):
             msg = "Both or neither of skymap_time and skymap_filename must be specified."
@@ -1619,7 +1623,9 @@ class VOEventList(APIView):
                 skymap_filename = skymap_filename, skymap_type = skymap_type,
                 skymap_image_filename = skymap_image_filename, internal = internal,
                 open_alert=open_alert, hardware_inj=hardware_inj,
-                CoincComment=CoincComment, ProbHasNS=ProbHasNS, ProbHasRemnant=ProbHasRemnant)
+                CoincComment=CoincComment, ProbHasNS=ProbHasNS,
+                ProbHasRemnant=ProbHasRemnant, BNS=BNS, NSBH=NSBH, BBH=BBH,
+                Terrestrial=Terrestrial)
 
         except VOEventBuilderException, e:
             msg = "Problem building VOEvent: %s" % str(e)
diff --git a/gracedb/api/v1/superevents/serializers.py b/gracedb/api/v1/superevents/serializers.py
index 31fbed00f0ce01739059e3f2d439a9295b7b0351..e4a688408f950f6b1b2d8d16089050138f663455 100644
--- a/gracedb/api/v1/superevents/serializers.py
+++ b/gracedb/api/v1/superevents/serializers.py
@@ -564,6 +564,14 @@ class SupereventVOEventSerializer(serializers.ModelSerializer):
         max_value=1, required=False)
     ProbHasRemnant = serializers.FloatField(write_only=True, min_value=0,
         max_value=1, required=False)
+    BNS = serializers.FloatField(write_only=True, min_value=0, max_value=1,
+        required=False)
+    NSBH = serializers.FloatField(write_only=True, min_value=0, max_value=1,
+        required=False)
+    BBH = serializers.FloatField(write_only=True, min_value=0, max_value=1,
+        required=False)
+    Terrestrial = serializers.FloatField(write_only=True, min_value=0,
+        max_value=1, required=False)
 
     class Meta:
         model = VOEvent
@@ -571,7 +579,8 @@ class SupereventVOEventSerializer(serializers.ModelSerializer):
             'issuer', 'filename', 'N', 'links', 'skymap_type',
             'skymap_filename', 'skymap_image_filename', 'internal',
             'open_alert', 'hardware_inj', 'CoincComment', 'ProbHasNS',
-            'ProbHasRemnant', 'superevent', 'user')
+            'ProbHasRemnant', 'BNS', 'NSBH', 'BBH', 'Terrestrial',
+            'superevent', 'user')
 
     def __init__(self, *args, **kwargs):
         super(SupereventVOEventSerializer, self).__init__(*args, **kwargs)
diff --git a/gracedb/api/v1/superevents/tests/test_access.py b/gracedb/api/v1/superevents/tests/test_access.py
index 303c9a84131e0e9d304604aef29088b138068057..bfd0b22500923c8da6f038d43bcd63aee5f29bf9 100644
--- a/gracedb/api/v1/superevents/tests/test_access.py
+++ b/gracedb/api/v1/superevents/tests/test_access.py
@@ -2438,6 +2438,9 @@ class TestSupereventVOEventList(SupereventSetup, GraceDbApiTestBase):
             'open_alert': False,
             'hardware_inj': False,
             'CoincComment': False,
+            'ProbHasRemnant': 0.5,
+            'BBH': 0.2,
+            'Terrestrial': 0.9,
         }
 
     def test_internal_user_get_voevent_list(self):
diff --git a/gracedb/events/buildVOEvent.py b/gracedb/events/buildVOEvent.py
index ddb120c4b0e078eb0f66123735912fb0be7e51f7..5086fe9a0e23fc560c8a99d7c7356a05f147e8c3 100644
--- a/gracedb/events/buildVOEvent.py
+++ b/gracedb/events/buildVOEvent.py
@@ -51,8 +51,9 @@ def get_voevent_type(short_name):
 
 def buildVOEvent(event, serial_number, voevent_type, request=None, skymap_filename=None,
                  skymap_type=None, skymap_image_filename=None, internal=True,
-                 open_alert=False, hardware_inj=False, CoincComment=False, ProbHasNS=None,
-                 ProbHasRemnant=None):
+                 open_alert=False, hardware_inj=False, CoincComment=False,
+                 ProbHasNS=None, ProbHasRemnant=None, BNS=None, NSBH=None,
+                 BBH=None, Terrestrial=None):
 
 # XXX Branson commenting out. Reed's MDC events do not have FAR for some reason.
 #    if not event.far:
@@ -314,6 +315,12 @@ def buildVOEvent(event, serial_number, voevent_type, request=None, skymap_filena
 
     # Analysis specific attributes
     if voevent_type != 'retraction':
+        classification_group = Group('Classification', Description=["Source "
+            "classification: binary neutron star (BNS), neutron star-black"
+            "hole (NSBH), binary black hole (BBH), or terrestrial (noise)"])
+        properties_group = Group('Properties', Description=["Qualitative "
+            "properties of the source, conditioned on the assumption that the "
+            "signal is an astrophysical compact binary merger"])
         if isinstance(event,CoincInspiralEvent) and voevent_type != 'retraction':
             # get mchirp and mass
             mchirp = float(event.mchirp)
@@ -322,37 +329,44 @@ def buildVOEvent(event, serial_number, voevent_type, request=None, skymap_filena
             eta = pow((mchirp/mass),5.0/3.0)
 
             # EM-Bright mass classifier information for CBC event candidates
-            if ProbHasNS!=None:
-                w.add_Param(Param(name="ProbHasNS",
-                    dataType="float",
-                    ucd="stat.probability",
-                    unit="",
-                    value=ProbHasNS,
-                    Description=["Probability that at least one object in the binary is less than 3 solar masses"]))
-
-            if ProbHasRemnant!=None:
-                w.add_Param(Param(name="ProbHasRemnant",
-                    dataType="float",
-                    ucd="stat.probability",
-                    unit="",
-                    value=ProbHasRemnant,
-                    Description=["Probability that there is matter in the surroundings of the central object"]))
-
-# XXX
-#            w.add_Param(Param(name="ChirpMass", 
-#                dataType="float", 
-#                ucd="phys.mass", 
-#                unit="solar mass",
-#                value=mchirp,
-#                Description=["Estimated CBC chirp mass"]))
-
-# XXX 
-#            w.add_Param(Param(name="Eta", 
-#                dataType="float", 
-#                ucd="phys.mass;arith.factor", 
-#                unit="",
-#                value=eta,
-#                Description=["Estimated ratio of reduced mass to total mass"]))
+            if ProbHasNS is not None:
+                properties_group.add_Param(Param(name="HasNS",
+                    dataType="float", ucd="stat.probability", unit="",
+                    value=ProbHasNS, Description=["Probability that at least "
+                    "one object in the binary has a mass that is less than "
+                    "3 solar masses"]))
+
+            if ProbHasRemnant is not None:
+                properties_group.add_Param(Param(name="HasRemnant",
+                    dataType="float", ucd="stat.probability",
+                    unit="", value=ProbHasRemnant,
+                    Description=["Probability that a nonzero mass was ejected "
+                    "outside the central remnant object"]))
+
+            if BNS is not None:
+                classification_group.add_Param(Param(name="BNS",
+                    dataType="float", ucd="stat.probability",
+                    unit="", value=BNS, Description=["Probability that the "
+                    "source is a binary neutron star merger"]))
+
+            if NSBH is not None:
+                classification_group.add_Param(Param(name="NSBH",
+                    dataType="float", ucd="stat.probability",
+                    unit="", value=NSBH, Description=["Probability that the "
+                    "source is a neutron star - black hole merger"]))
+
+            if BBH is not None:
+                classification_group.add_Param(Param(name="BBH",
+                    dataType="float", ucd="stat.probability",
+                    unit="", value=BBH, Description=["Probability that the "
+                    "source is a binary black hole merger"]))
+
+            if Terrestrial is not None:
+                classification_group.add_Param(Param(name="Terrestrial",
+                    dataType="float", ucd="stat.probability",
+                    unit="", value=Terrestrial, Description=["Probability "
+                    "that the source is terrestrial (i.e., a background noise "
+                    "fluctuation or a glitch)"]))
 
             # build up MaxDistance. event.singleinspiral_set.all()?
             # Each detector calculates an effective distance assuming the inspiral is 
@@ -452,6 +466,9 @@ def buildVOEvent(event, serial_number, voevent_type, request=None, skymap_filena
                 pass
         else:
             pass
+        # Add Groups to What block
+        w.add_Group(classification_group)
+        w.add_Group(properties_group)
 
     v.set_What(w)
 
diff --git a/gracedb/superevents/buildVOEvent.py b/gracedb/superevents/buildVOEvent.py
index 2e374bd83e8591f4e54acdb909868023638832e7..40d7ab9794e482d011056ee17af0a4692e961743 100644
--- a/gracedb/superevents/buildVOEvent.py
+++ b/gracedb/superevents/buildVOEvent.py
@@ -54,7 +54,8 @@ def get_voevent_type(short_name):
 def construct_voevent_file(superevent, voevent, request=None,
     skymap_filename=None, skymap_type=None, skymap_image_filename=None,
     internal=True, open_alert=False, hardware_inj=False, CoincComment=False,
-    ProbHasNS=None, ProbHasRemnant=None):
+    ProbHasNS=None, ProbHasRemnant=None, BNS=None, NSBH=None, BBH=None,
+    Terrestrial=None):
 
     # Set preferred_event as event to be used in most of this
     event = superevent.preferred_event
@@ -302,6 +303,12 @@ def construct_voevent_file(superevent, voevent, request=None,
 
     # Analysis specific attributes
     if voevent_type != 'retraction':
+        classification_group = Group('Classification', Description=["Source "
+            "classification: binary neutron star (BNS), neutron star-black"
+            "hole (NSBH), binary black hole (BBH), or terrestrial (noise)"])
+        properties_group = Group('Properties', Description=["Qualitative "
+            "properties of the source, conditioned on the assumption that the "
+            "signal is an astrophysical compact binary merger"])
         if isinstance(event, CoincInspiralEvent) and voevent_type != 'retraction':
             # get mchirp and mass
             mchirp = float(event.mchirp)
@@ -310,21 +317,44 @@ def construct_voevent_file(superevent, voevent, request=None,
             eta = pow((mchirp/mass),5.0/3.0)
 
             # EM-Bright mass classifier information for CBC event candidates
-            if ProbHasNS!=None:
-                w.add_Param(Param(name="ProbHasNS",
-                    dataType="float",
-                    ucd="stat.probability",
-                    unit="",
-                    value=ProbHasNS,
-                    Description=["Probability that at least one object in the binary is less than 3 solar masses"]))
-
-            if ProbHasRemnant!=None:
-                w.add_Param(Param(name="ProbHasRemnant",
-                    dataType="float",
-                    ucd="stat.probability",
-                    unit="",
-                    value=ProbHasRemnant,
-                    Description=["Probability that there is matter in the surroundings of the central object"]))
+            if ProbHasNS is not None:
+                properties_group.add_Param(Param(name="HasNS",
+                    dataType="float", ucd="stat.probability", unit="",
+                    value=ProbHasNS, Description=["Probability that at least "
+                    "one object in the binary has a mass that is less than "
+                    "3 solar masses"]))
+
+            if ProbHasRemnant is not None:
+                properties_group.add_Param(Param(name="HasRemnant",
+                    dataType="float", ucd="stat.probability",
+                    unit="", value=ProbHasRemnant,
+                    Description=["Probability that a nonzero mass was ejected "
+                    "outside the central remnant object"]))
+
+            if BNS is not None:
+                classification_group.add_Param(Param(name="BNS",
+                    dataType="float", ucd="stat.probability",
+                    unit="", value=BNS, Description=["Probability that the "
+                    "source is a binary neutron star merger"]))
+
+            if NSBH is not None:
+                classification_group.add_Param(Param(name="NSBH",
+                    dataType="float", ucd="stat.probability",
+                    unit="", value=NSBH, Description=["Probability that the "
+                    "source is a neutron star - black hole merger"]))
+
+            if BBH is not None:
+                classification_group.add_Param(Param(name="BBH",
+                    dataType="float", ucd="stat.probability",
+                    unit="", value=BBH, Description=["Probability that the "
+                    "source is a binary black hole merger"]))
+
+            if Terrestrial is not None:
+                classification_group.add_Param(Param(name="Terrestrial",
+                    dataType="float", ucd="stat.probability",
+                    unit="", value=Terrestrial, Description=["Probability "
+                    "that the source is terrestrial (i.e., a background noise "
+                    "fluctuation or a glitch)"]))
 
             # build up MaxDistance. event.singleinspiral_set.all()?
             # Each detector calculates an effective distance assuming the inspiral is 
@@ -416,6 +446,10 @@ def construct_voevent_file(superevent, voevent, request=None,
             except Exception as e:
                 logger.exception(e)
 
+        # Add Groups to What block
+        w.add_Group(classification_group)
+        w.add_Group(properties_group)
+
     v.set_What(w)
 
     ############ Wherewhen ############################
diff --git a/gracedb/superevents/utils.py b/gracedb/superevents/utils.py
index 9c317e4f41be5c8cd8b79146dd53af13b8da5765..1d667a014bd1924c65488fe4c6b1155f5df0f1dc 100644
--- a/gracedb/superevents/utils.py
+++ b/gracedb/superevents/utils.py
@@ -560,8 +560,9 @@ def create_emobservation_for_superevent(superevent, submitter, ra_list,
 def create_voevent_for_superevent(superevent, issuer, voevent_type,
     skymap_type=None, skymap_filename=None, skymap_image_filename=None,
     internal=True, open_alert=False, hardware_inj=False,
-    CoincComment=False, ProbHasNS=None, ProbHasRemnant=None,
-    add_log_message=True, issue_alert=True):
+    CoincComment=False, ProbHasNS=None, ProbHasRemnant=None, BNS=None,
+    NSBH=None, BBH=None, Terrestrial=None, add_log_message=True,
+    issue_alert=True):
 
     # Instantiate VOEvent object
     voevent = VOEvent.objects.create(superevent=superevent, issuer=issuer,
@@ -573,7 +574,8 @@ def create_voevent_for_superevent(superevent, issuer, voevent_type,
         skymap_image_filename=skymap_image_filename, internal=internal,
         open_alert=open_alert, hardware_inj=hardware_inj,
         CoincComment=CoincComment, ProbHasNS=ProbHasNS,
-        ProbHasRemnant=ProbHasRemnant)
+        ProbHasRemnant=ProbHasRemnant, BNS=BNS, NSBH=NSBH, BBH=BBH,
+        Terrestrial=Terrestrial)
 
     # Save versioned VOEvent file
     voevent_display_type = dict(VOEvent.VOEVENT_TYPE_CHOICES) \