diff --git a/gracedb/api.py b/gracedb/api.py
index f317ca9475ce7f14ca21643059f2362722b18d10..b4384f9c9caa843d66af748e6a5de9a3dba27e47 100644
--- a/gracedb/api.py
+++ b/gracedb/api.py
@@ -12,6 +12,7 @@ import json
 from gracedb.models import Event, Group, Search, Pipeline, EventLog, Tag
 from view_logic import create_label, get_performance_info
 from view_logic import _createEventFromForm
+from view_utils import fix_old_creation_request
 from translator import handle_uploaded_data
 from forms import CreateEventForm
 
@@ -521,13 +522,21 @@ class EventList(APIView):
         return response
 
     def post(self, request, format=None):
+
+        # XXX Deal with POSTs coming in from the old client.
+        # Eventually, we will want to get rid of this check and just let it fail.
+        rv = {}
+        if 'type' in request.POST:
+            request = fix_old_creation_request(request)
+            rv['warnings'] = 'It looks like you are using the old GraceDB client (v<=1.14). ' + \
+                             'Please update! This will eventually stop working.'
+
         form = CreateEventForm(request.POST, request.FILES)
         if form.is_valid():
             event, warnings = _createEventFromForm(request, form)
             if event:
-                response = Response(
-                        eventToDict(event, request=request),
-                        status=status.HTTP_201_CREATED)
+                rv.update(eventToDict(event, request=request))
+                response = Response(rv, status=status.HTTP_201_CREATED)
                 response["Location"] = reverse(
                         'event-detail',
                         args=[event.graceid()],
@@ -1296,6 +1305,22 @@ class GracedbRoot(APIView):
             "groups"    : [group.name for group in Group.objects.all()],
             "pipelines" : [pipeline.name for pipeline in Pipeline.objects.all()],
             "searches"  : [search.name for search in Search.objects.all()],
+            # XXX Retained for compatibility with old clients (v<=1.14).
+            # Should eventually be removed.
+            "analysis-types" : dict(
+                    (
+                        ("LM",  "LowMass"),
+                        ("HM",  "HighMass"),
+                        ("GRB", "GRB"),
+                        ("RD",  "Ringdown"),
+                        ("OM",  "Omega"),
+                        ("Q",   "Q"),
+                        ("X",   "X"),
+                        ("CWB", "CWB"),
+                        ("MBTA", "MBTAOnline"), 
+                        ("HWINJ", "HardwareInjection"),
+                    ) 
+                ),
            })
 
 ##################################################################
diff --git a/gracedb/view_utils.py b/gracedb/view_utils.py
index 6015fff40c2c9421543f4b54c65cfc7c1e3dcd44..5333b45e8cd8498252a46c91153e3ecc8db820c0 100644
--- a/gracedb/view_utils.py
+++ b/gracedb/view_utils.py
@@ -168,4 +168,84 @@ def get_file(graceid, filename="event.log"):
         contents = None
     return contents
 
+#
+# A utility to 'fix' an event creation request coming from the old client.
+# The old client will provide 'analysisType' instead of 'pipeline' and 
+# 'search'. We will need to make an educated guess about the latter values
+# and stuff them into the POST dictionary *before* we try to bind the data
+# to the event creation form. This is modeled after migration 23, which 
+# attempts to set 'pipeline' and 'search' on old events from the 
+# analysisType era.
+#
+
+GSTLAL_SPIIR_SUBMITTERS = ['gstlal-spiir', 'qi.chu@LIGO.ORG', 'shinkee.chung@LIGO.ORG',]
+
+ANALYSIS_TYPE_TO_PIPELINE = {
+    'RD' : 'Ringdown',
+    'OM' : 'Omega',
+    'Q'  : 'Q',
+    'X'  : 'X',
+    'MBTA' : 'MBTAOnline',
+    'HWINJ' : 'HardwareInjection',
+}
+
+from VOEventLib.Vutil import parseString
+
+def fix_old_creation_request(request):
+    if not 'type' in request.POST:
+        # Fix apparently invoked by mistake.
+        return request
+    else:
+        group = request.POST['group']
+        atype = request.POST['type']
+        username = request.user.username
+
+        if atype=="LM":
+            if group=='Test':
+                search = 'Test'
+            else:
+                search = 'LowMass'
+
+            if username in GSTLAL_SPIIR_SUBMITTERS:
+                pipeline = 'gstlal-spiir'
+            else:
+                pipeline = 'gstlal'
+        elif atype=="HM":
+            if group=='Test':
+                search = 'Test'
+            else:
+                search = 'HighMass'
+
+            if username in GSTLAL_SPIIR_SUBMITTERS:
+                pipeline = 'gstlal-spiir'
+            else:
+                pipeline = 'gstlal'
+        # If the event is a GRB, decide whether it came from Fermi or 
+        # Swift. Assign all GRBs to the search 'GRB'.
+        elif atype=="GRB":
+            # Gonna have to crack the file open. Hopefully this won't actually consume it?
+            f = request.FILES['eventFile']
+            v = parseString(f.read())
+            how_description = v.get_How().get_Description()[0]
+            if how_description.startswith('Fermi'):
+                pipeline = 'Fermi'
+            else:
+                pipeline = 'Swift'
+            search = 'GRB'
+        # For all other analysis types, we just map the analysis type
+        # to the pipeline, and leave the search blank.
+        elif atype=="CWB":
+            pipeline = 'CWB'
+            search = 'AllSky'
+        elif atype in ANALYSIS_TYPE_TO_PIPELINE.keys():
+            pipeline = ANALYSIS_TYPE_TO_PIPELINE[atype]
+            search = None
+        else:
+            raise Exception("What kind of event is this anyway? atype=%s" % atype)
+        request.POST['pipeline'] = pipeline
+        request.POST['search'] = search
+        return request
+
+
+