diff --git a/geomagio/api/db/MetadataDatabaseFactory.py b/geomagio/api/db/MetadataDatabaseFactory.py
index bb494b0c6e58bb8959a8bd1e2f02bbd355627874..d221c4de48cb9bca4bdeb825739b658393e7cc7c 100644
--- a/geomagio/api/db/MetadataDatabaseFactory.py
+++ b/geomagio/api/db/MetadataDatabaseFactory.py
@@ -1,8 +1,6 @@
 from datetime import datetime
-from enum import Enum
-from typing import List, Union
+from typing import List
 
-from fastapi import Response
 from obspy import UTCDateTime
 from sqlalchemy import or_, Table
 
@@ -12,11 +10,6 @@ from .metadata_history_table import metadata_history
 from .metadata_table import metadata
 
 
-class TableType(str, Enum):
-    METADATA = "metadata"
-    HISTORY = "history"
-
-
 class MetadataDatabaseFactory(object):
     def __init__(
         self, table: Table = metadata, history_table: Table = metadata_history
@@ -24,38 +17,20 @@ class MetadataDatabaseFactory(object):
         self.table = table
         self.history_table = history_table
 
-    async def create_metadata(
-        self, meta: Metadata, table: TableType = TableType.METADATA
-    ) -> Metadata:
-        exclude = {"id"}
-        if table is TableType.HISTORY:
-            query = self.history_table.insert()
-            meta.metadata_id = meta.id
-        else:
-            query = self.table.insert()
-            exclude.add("metadata_id")
-        values = meta.datetime_dict(exclude=exclude, exclude_none=True)
+    async def create_metadata(self, meta: Metadata) -> Metadata:
+        query = metadata.insert()
+        values = meta.datetime_dict(exclude={"id", "metadata_id"}, exclude_none=True)
         query = query.values(**values)
         meta.id = await database.execute(query)
         return meta
 
-    async def delete_metadata(self, id: int) -> None:
-        query = self.table.delete().where(self.table.c.id == id)
-        await database.execute(query)
-
-    async def get_metadata_by_id(
-        self, id: int, table: TableType = TableType.METADATA
-    ) -> Union[Metadata, List[Metadata]]:
-        if table == TableType.HISTORY:
-            query = self.history_table.select()
-            query = query.where(self.history_table.c.metadata_id == id)
-            rows = await database.fetch_all(query)
-            return [Metadata(**row) for row in rows]
-        meta = await self.get_metadata(id=id)
-        if len(meta) != 1:
-            return Response(status_code=404)
-        else:
-            return meta[0]
+    async def create_metadata_history(self, meta: Metadata) -> Metadata:
+        query = self.history_table.insert()
+        meta.metadata_id = meta.id
+        values = meta.datetime_dict(exclude={"id"}, exclude_none=True)
+        query = query.values(**values)
+        meta.id = await database.execute(query)
+        return meta
 
     async def get_metadata(
         self,
@@ -73,7 +48,8 @@ class MetadataDatabaseFactory(object):
         data_valid: bool = None,
         metadata_valid: bool = None,
         reviewed: bool = None,
-    ) -> List[Metadata]:
+        status: str = None,
+    ):
         table = self.table
         query = table.select()
         if id:
@@ -90,11 +66,17 @@ class MetadataDatabaseFactory(object):
             query = query.where(table.c.location.like(location))
         if starttime:
             query = query.where(
-                or_(table.c.endtime == None, table.c.endtime > starttime)
+                or_(
+                    table.c.endtime == None,
+                    table.c.endtime > starttime,
+                )
             )
         if endtime:
             query = query.where(
-                or_(table.c.starttime == None, table.c.starttime < endtime)
+                or_(
+                    table.c.starttime == None,
+                    table.c.starttime < endtime,
+                )
             )
         if created_after:
             query = query.where(table.c.created_time > created_after)
@@ -106,21 +88,39 @@ class MetadataDatabaseFactory(object):
             query = query.where(table.c.metadata_valid == metadata_valid)
         if reviewed is not None:
             query = query.where(table.c.reviewed == reviewed)
+        if status is not None:
+            query = query.where(table.c.status == status)
         rows = await database.fetch_all(query)
         return [Metadata(**row) for row in rows]
 
+    async def get_metadata_by_id(self, id: int):
+        meta = await self.get_metadata(id=id)
+        if len(meta) != 1:
+            raise ValueError(f"{len(meta)} records found")
+        return meta[0]
+
+    async def get_metadata_history(self, metadata_id: int) -> List[Metadata]:
+        query = self.history_table.select()
+        query = query.where(self.history_table.c.metadata_id == metadata_id)
+        rows = await database.fetch_all(query)
+        metadata = [Metadata(**row) for row in rows]
+        current_metadata = await self.get_metadata_by_id(id=metadata_id)
+        metadata.append(current_metadata)
+        # return records in order of age
+        metadata.reverse()
+        return metadata
+
     async def update_metadata(
-        self,
-        meta: Metadata,
-        username: str,
+        self, meta: Metadata, username: str, status: str = None
     ) -> Metadata:
-        original_metadata = await self.get_metadata_by_id(id=meta.id)
-        await self.create_metadata(meta=original_metadata, table=TableType.HISTORY)
-        meta.updated_by = username
-        meta.updated_time = UTCDateTime()
-        query = self.table.update().where(self.table.c.id == meta.id)
-        values = meta.datetime_dict(exclude={"id", "metadata_id"})
-        query = query.values(**values)
-        await database.execute(query)
-        updated_metadata = await self.get_metadata_by_id(id=meta.id)
-        return updated_metadata
+        async with database.transaction() as transaction:
+            original_metadata = await self.get_metadata_by_id(id=meta.id)
+            await self.create_metadata_history(meta=original_metadata)
+            meta.updated_by = username
+            meta.updated_time = UTCDateTime()
+            meta.status = status or meta.status
+            query = self.table.update().where(self.table.c.id == meta.id)
+            values = meta.datetime_dict(exclude={"id", "metadata_id"})
+            query = query.values(**values)
+            await database.execute(query)
+        return await self.get_metadata_by_id(id=meta.id)
diff --git a/geomagio/api/db/metadata_table.py b/geomagio/api/db/metadata_table.py
index a99def5c74c3d6450432fd4830bc8f673f6e1130..c80567828aac49c19ac310f2bf894eb22a7aa4a5 100644
--- a/geomagio/api/db/metadata_table.py
+++ b/geomagio/api/db/metadata_table.py
@@ -42,6 +42,8 @@ metadata = Table(
     Column("metadata_valid", Boolean, default=True, index=True),
     # whether metadata has been reviewed
     Column("reviewed", Boolean, default=True, index=True),
+    # deletion status indicator
+    Column("status", String(length=255), nullable=True),
     # metadata json blob
     Column("metadata", JSON, nullable=True),
     # general comment
@@ -65,6 +67,7 @@ metadata = Table(
         "metadata_valid",
         "data_valid",
         "reviewed",
+        "status",
     ),
     Index(
         "index_category_time",
diff --git a/geomagio/api/secure/metadata.py b/geomagio/api/secure/metadata.py
index 07f7a65427e8e309fa3015451caa026852e10d06..baf4094a0f4227c3cc225c2a406a731ef218ec70 100644
--- a/geomagio/api/secure/metadata.py
+++ b/geomagio/api/secure/metadata.py
@@ -34,7 +34,7 @@ async def create_metadata(
     metadata: Metadata,
     user: User = Depends(require_user()),
 ):
-    metadata = await MetadataDatabaseFactory().create_metadata(metadata)
+    metadata = await MetadataDatabaseFactory().create_metadata(meta=metadata)
     return Response(metadata.json(), status_code=201, media_type="application/json")
 
 
@@ -42,14 +42,11 @@ async def create_metadata(
 async def delete_metadata(
     id: int, user: User = Depends(require_user([os.getenv("ADMIN_GROUP", "admin")]))
 ):
-    await MetadataDatabaseFactory().delete_metadata(id)
-
-
-@router.get("/metadata/{id}/history", response_model=List[Metadata])
-async def get_metadata_history(
-    id: int,
-):
-    return await MetadataDatabaseFactory().get_metadata_by_id(id=id, table="history")
+    database_factory = MetadataDatabaseFactory()
+    metadata = await database_factory.get_metadata_by_id(id=id)
+    await database_factory.update_metadata(
+        meta=metadata, username=user.nickname, status="deleted"
+    )
 
 
 @router.get("/metadata", response_model=List[Metadata])
@@ -66,6 +63,7 @@ async def get_metadata(
     data_valid: bool = None,
     metadata_valid: bool = True,
     reviewed: bool = None,
+    status: str = None,
 ):
     query = MetadataQuery(
         category=category,
@@ -80,9 +78,10 @@ async def get_metadata(
         data_valid=data_valid,
         metadata_valid=metadata_valid,
         reviewed=reviewed,
+        status=status,
     )
     metas = await MetadataDatabaseFactory().get_metadata(
-        **query.datetime_dict(exclude={"id"})
+        **query.datetime_dict(exclude={"id", "metadata_id"})
     )
     return metas
 
@@ -92,6 +91,15 @@ async def get_metadata_by_id(id: int):
     return await MetadataDatabaseFactory().get_metadata_by_id(id=id)
 
 
+@router.get("/metadata/{metadata_id}/history", response_model=List[Metadata])
+async def get_metadata_history(
+    metadata_id: int,
+):
+    return await MetadataDatabaseFactory().get_metadata_history(
+        metadata_id=metadata_id,
+    )
+
+
 @router.put("/metadata/{id}", response_model=Metadata)
 async def update_metadata(
     id: int,
@@ -99,6 +107,5 @@ async def update_metadata(
     user: User = Depends(require_user([os.getenv("REVIEWER_GROUP", "reviewer")])),
 ):
     return await MetadataDatabaseFactory().update_metadata(
-        meta=metadata,
-        username=user.nickname,
+        meta=metadata, username=user.nickname
     )
diff --git a/geomagio/api/ws/metadata.py b/geomagio/api/ws/metadata.py
index 827fdcaf6208a77a1b06a2c240e93caa29f24ed4..57b89cb3049bf4f2b1ae3f72aaf33e90c7d6113c 100644
--- a/geomagio/api/ws/metadata.py
+++ b/geomagio/api/ws/metadata.py
@@ -21,6 +21,7 @@ async def get_metadata(
     data_valid: bool = None,
     metadata_valid: bool = True,
     reviewed: bool = None,
+    status: str = None,
 ):
     query = MetadataQuery(
         category=category,
@@ -33,6 +34,7 @@ async def get_metadata(
         data_valid=data_valid,
         metadata_valid=metadata_valid,
         reviewed=reviewed,
+        status=status,
     )
     metas = await MetadataDatabaseFactory().get_metadata(
         **query.datetime_dict(exclude={"id"})
diff --git a/geomagio/metadata/Metadata.py b/geomagio/metadata/Metadata.py
index 4dede4eeec2778f67a03b740bc465c7fb0325aad..b6bcb6ba04f9da7692010636ba2a76cbb3272e60 100644
--- a/geomagio/metadata/Metadata.py
+++ b/geomagio/metadata/Metadata.py
@@ -80,6 +80,8 @@ class Metadata(BaseModel):
     comment: str = None
     # review specific comment
     review_comment: str = None
+    # deletion status indicator
+    status: str = None
 
     def datetime_dict(self, **kwargs):
         values = self.dict(**kwargs)
diff --git a/geomagio/metadata/MetadataQuery.py b/geomagio/metadata/MetadataQuery.py
index dd80ae06729915a6a04a2531bd7eb3d548180fd0..025c000b720511bbd4238f029241d583710b587e 100644
--- a/geomagio/metadata/MetadataQuery.py
+++ b/geomagio/metadata/MetadataQuery.py
@@ -22,6 +22,7 @@ class MetadataQuery(BaseModel):
     data_valid: Optional[bool] = None
     metadata_valid: Optional[bool] = None
     reviewed: Optional[bool] = None
+    status: Optional[str] = None
 
     def datetime_dict(self, **kwargs):
         values = self.dict(**kwargs)
diff --git a/geomagio/metadata/main.py b/geomagio/metadata/main.py
index 863052286d5a04bfcc69a533d3f6f102eb1a975a..1b7c8da81289523cab910e66f07088d91d089a1d 100644
--- a/geomagio/metadata/main.py
+++ b/geomagio/metadata/main.py
@@ -148,6 +148,7 @@ def get(
     metadata_valid: Optional[bool] = None,
     network: Optional[str] = None,
     reviewed: Optional[bool] = None,
+    status: Optional[str] = None,
     starttime: Optional[str] = None,
     station: Optional[str] = None,
     url: str = GEOMAG_API_URL,
@@ -166,6 +167,7 @@ def get(
         reviewed=reviewed,
         starttime=UTCDateTime(starttime) if starttime else None,
         station=station,
+        status=status,
     )
     metadata = MetadataFactory(url=url).get_metadata(query=query)
     if getone: