diff --git a/app/models.py b/app/models.py
index 99e32c9a59605d3032883a0d00e78d990dcc355c..265e19c905ab35ed359ee43812e208224f2f10c4 100644
--- a/app/models.py
+++ b/app/models.py
@@ -262,6 +262,15 @@ class CreatedMixin:
     def user(cls):
         return db.relationship('User')
 
+    def __init__(self, **kwargs):
+        # Automatically convert created_at/updated_at strings
+        # to datetime object
+        for key in ('created_at', 'updated_at'):
+            if key in kwargs:
+                if isinstance(kwargs[key], str):
+                    kwargs[key] = utils.parse_to_utc(kwargs[key])
+        super().__init__(**kwargs)
+
     def to_dict(self):
         return {
             'id': self.id,
diff --git a/app/utils.py b/app/utils.py
index 7f9c8b84a3296db93cf2dcc1b35ee9aa91475ffc..e2c78dcaf27c984fb54240a11bc1a9ab1bde50b5 100644
--- a/app/utils.py
+++ b/app/utils.py
@@ -13,6 +13,7 @@ import base64
 import datetime
 import io
 import sqlalchemy as sa
+import dateutil.parser
 from flask.globals import _app_ctx_stack, _request_ctx_stack
 from flask_login import current_user
 from flask_jwt_extended import get_current_user
@@ -168,3 +169,14 @@ def coerce_to_str_or_none(value):
     if not value or value == 'None':
         return None
     return str(value)
+
+
+def parse_to_utc(string):
+    """Convert a string to a datetime object with no timezone"""
+    d = dateutil.parser.parse(string)
+    if d.tzinfo is None:
+        # Assume this is UTC
+        return d
+    # Convert to UTC and remove timezone
+    d = d.astimezone(datetime.timezone.utc)
+    return d.replace(tzinfo=None)