diff --git a/src/api/tests/messages.py b/src/api/tests/messages.py
index 77b9649dce27d2a15509435bb31c341290696783..fdde3af340a281b68309a49f2c4e4ac42a1c5927 100644
--- a/src/api/tests/messages.py
+++ b/src/api/tests/messages.py
@@ -318,3 +318,54 @@ class MessagesTestCase(TestCase):
         self.assertEqual(DirectMessage.objects.all().count(), 3)
         dm3 = DirectMessage.objects.get(pk=resp.json()['id'])
         self.assertTrue(dm3.deleted_by_recipient)
+
+    def test_DirectMessageDelete(self):
+        c = Client()
+        resp = c.delete(reverse('api:my-delete-message', kwargs={'pk': str(uuid.uuid4())}))
+        self.assertEqual(resp.status_code, 403)
+        c.force_login(self.human_user1)
+
+        dm = DirectMessage(
+            conference=self.conference1,
+            sender=self.human_user1,
+            recipient=self.human_user2,
+            timestamp=datetime(2020, 5, 4, 3, 2, 1, tzinfo=UTC),
+            subject='Test Message',
+            body='Message Body',
+        )
+        dm.save()
+
+        resp = c.delete(reverse('api:my-delete-message', kwargs={'pk': str(dm.pk)}))
+        self.assertEqual(resp.status_code, 204)
+        dm.refresh_from_db()
+        self.assertTrue(dm.deleted_by_sender)
+        self.assertFalse(dm.deleted_by_recipient)
+
+        dm = DirectMessage(
+            conference=self.conference1,
+            sender=self.human_user2,
+            recipient=self.human_user1,
+            timestamp=datetime(2020, 1, 2, 3, 4, 5, tzinfo=UTC),
+            subject='Test Message2',
+            body='Message Body2',
+        )
+        dm.save()
+        resp = c.delete(reverse('api:my-delete-message', kwargs={'pk': str(dm.pk)}))
+        self.assertEqual(resp.status_code, 204)
+        dm.refresh_from_db()
+        self.assertFalse(dm.deleted_by_sender)
+        self.assertTrue(dm.deleted_by_recipient)
+
+        dm = DirectMessage(
+            conference=self.conference1,
+            sender=self.human_user2,
+            recipient=self.human_user1,
+            timestamp=datetime(2020, 2, 2, 2, 2, 2, tzinfo=UTC),
+            deleted_by_sender=True,
+            subject='Test Message3',
+            body='Message Body3',
+        )
+        dm.save()
+        resp = c.delete(reverse('api:my-delete-message', kwargs={'pk': str(dm.pk)}))
+        self.assertEqual(resp.status_code, 204)
+        self.assertEqual(DirectMessage.objects.filter(pk=dm.pk).count(), 0)
diff --git a/src/api/urls.py b/src/api/urls.py
index b92ea88dca3a9781b96bf6d0306ee9fa74f345ef..8b618b9743729cffacb04f7193e364b5eb4cd352 100644
--- a/src/api/urls.py
+++ b/src/api/urls.py
@@ -20,6 +20,7 @@ urlpatterns = [
     path('me/received-messages/<uuid:pk>', messages.DirectMessageReceived.as_view(), name='my-message-received'),
     path('me/sent-messages/<uuid:pk>', messages.DirectMessageSent.as_view(), name='my-message-sent'),
     path('me/send-message', messages.DirectMessageSend.as_view(), name='my-send-message'),
+    path('me/delete-message/<uuid:pk>', messages.DirectMessageDelete.as_view(), name='my-delete-message'),
     path('me/friends', users.friends, name='friends'),
     path('me/timeline', users.UserTimelineList.as_view(), name='timeline-list'),
     # conference-specific views
diff --git a/src/api/views/messages.py b/src/api/views/messages.py
index 1e9adb8176771bc3d75ee2fb19fb7a0949e25a40..01a3ecf3266d9f84dc9f302736355978944ee579 100644
--- a/src/api/views/messages.py
+++ b/src/api/views/messages.py
@@ -1,9 +1,16 @@
-from django.conf import settings
 from rest_framework import generics, permissions
 
+from django.db.models import Q
+
 from core.models.messages import DirectMessage
 
-from ..serializers import DirectMessageSerializerReceived, DirectMessageSerializerReceivedShort, DirectMessageSerializerSent, DirectMessageSerializerSentShort, DirectMessageSendSerializer
+from ..serializers import (
+    DirectMessageSendSerializer,
+    DirectMessageSerializerReceived,
+    DirectMessageSerializerReceivedShort,
+    DirectMessageSerializerSent,
+    DirectMessageSerializerSentShort,
+)
 from .mixins import ConferenceSlugMixin
 
 
@@ -65,3 +72,30 @@ class DirectMessageSend(ConferenceSlugMixin, generics.CreateAPIView):
             sender=self.request.user,
             deleted_by_recipient=self.request.user != serializer.validated_data['recipient'] and self.request.user.shadow_banned,
         )
+
+
+class DirectMessageDelete(ConferenceSlugMixin, generics.DestroyAPIView):
+    permission_classes = [permissions.IsAuthenticated]
+
+    def get_queryset(self):
+        return DirectMessage.objects.filter(
+            Q(conference=self.conference, recipient=self.request.user, deleted_by_recipient=False)
+            | Q(conference=self.conference, sender=self.request.user, deleted_by_sender=False)
+        )
+
+    def perform_destroy(self, instance: DirectMessage):
+        if instance.sender == self.request.user:
+            if instance.deleted_by_recipient:
+                instance.delete()
+                return
+
+            instance.deleted_by_sender = True
+            instance.save(update_fields=['deleted_by_sender'])
+
+        elif instance.recipient == self.request.user:
+            if instance.deleted_by_sender:
+                instance.delete()
+                return
+
+            instance.deleted_by_recipient = True
+            instance.save(update_fields=['deleted_by_recipient'])