diff --git a/app/admin.py b/app/admin.py
index f23c53e..f8d8fa3 100644
--- a/app/admin.py
+++ b/app/admin.py
@@ -427,6 +427,18 @@ async def admin_actions_follow(
     return RedirectResponse(redirect_url, status_code=302)
 
 
+@router.post("/actions/delete")
+async def admin_actions_delete(
+    request: Request,
+    ap_object_id: str = Form(),
+    redirect_url: str = Form(),
+    csrf_check: None = Depends(verify_csrf_token),
+    db_session: AsyncSession = Depends(get_db_session),
+) -> RedirectResponse:
+    await boxes.send_delete(db_session, ap_object_id)
+    return RedirectResponse(redirect_url, status_code=302)
+
+
 @router.post("/actions/like")
 async def admin_actions_like(
     request: Request,
diff --git a/app/boxes.py b/app/boxes.py
index 37cdb0f..f00d04a 100644
--- a/app/boxes.py
+++ b/app/boxes.py
@@ -76,6 +76,39 @@ async def save_outbox_object(
     return outbox_object
 
 
+async def send_delete(db_session: AsyncSession, ap_object_id: str) -> None:
+    outbox_object_to_delete = await get_outbox_object_by_ap_id(db_session, ap_object_id)
+    if not outbox_object_to_delete:
+        raise ValueError(f"{ap_object_id} not found in the outbox")
+
+    delete_id = allocate_outbox_id()
+    delete = {
+        "@context": ap.AS_CTX,
+        "id": outbox_object_id(delete_id),
+        "type": "Delete",
+        "actor": ID,
+        "object": ap_object_id,
+    }
+    outbox_object = await save_outbox_object(
+        db_session,
+        delete_id,
+        delete,
+        relates_to_outbox_object_id=outbox_object_to_delete.id,
+    )
+    if not outbox_object.id:
+        raise ValueError("Should never happen")
+
+    outbox_object_to_delete.is_deleted = True
+    await db_session.commit()
+
+    # Compute the original recipients
+    recipients = await _compute_recipients(
+        db_session, outbox_object_to_delete.ap_object
+    )
+    for rcp in recipients:
+        await new_outgoing_activity(db_session, rcp, outbox_object.id)
+
+
 async def send_like(db_session: AsyncSession, ap_object_id: str) -> None:
     inbox_object = await get_inbox_object_by_ap_id(db_session, ap_object_id)
     if not inbox_object:
diff --git a/app/outgoing_activities.py b/app/outgoing_activities.py
index ed180de..3903132 100644
--- a/app/outgoing_activities.py
+++ b/app/outgoing_activities.py
@@ -99,8 +99,11 @@ def process_next_outgoing_activity(db: Session) -> bool:
     next_activity.last_try = now()
 
     payload = ap.wrap_object_if_needed(next_activity.outbox_object.ap_object)
-    if payload["type"] == "Create":
+
+    # Use LD sig if the activity may need to be forwarded by recipients
+    if payload["type"] in ["Create", "Delete"]:
         ldsig.generate_signature(payload, k)
+
     logger.info(f"{payload=}")
     try:
         resp = ap.post(next_activity.recipient, payload)
diff --git a/app/templates/admin_outbox.html b/app/templates/admin_outbox.html
index 51f1078..fcdbc20 100644
--- a/app/templates/admin_outbox.html
+++ b/app/templates/admin_outbox.html
@@ -16,6 +16,7 @@
         <div class="actor-action">You followed</div>
         {{ utils.display_actor(outbox_object.relates_to_actor, actors_metadata) }}
     {% elif outbox_object.ap_type in ["Article", "Note", "Video"] %}
+        {% if outbox_object.is_deleted %}Deleted{% endif %}
         {{ utils.display_object(outbox_object) }}
     {% else %}
         Implement {{ outbox_object.ap_type }}
diff --git a/app/templates/utils.html b/app/templates/utils.html
index 393fc0c..6e15c8c 100644
--- a/app/templates/utils.html
+++ b/app/templates/utils.html
@@ -60,6 +60,15 @@
 </form>
 {% endmacro %}
 
+{% macro admin_delete_button(ap_object_id) %}
+<form action="{{ request.url_for("admin_actions_delete") }}" method="POST" onsubmit="return confirm('Do you really want to delete this object?');">
+    {{ embed_csrf_token() }}
+    {{ embed_redirect_url() }}
+    <input type="hidden" name="ap_object_id" value="{{ ap_object_id }}">
+    <input type="submit" value="Delete">
+</form>
+{% endmacro %}
+
 {% macro admin_announce_button(ap_object_id, disabled=False) %}
 <form action="{{ request.url_for("admin_actions_announce") }}" method="POST">
     {{ embed_csrf_token() }}
@@ -320,6 +329,9 @@
     </div>
 
     {% if is_admin %}
+    <div class="bar-item">
+        {{ admin_delete_button(object.ap_id) }}
+    </div>
     <div class="bar-item">
         {{ admin_reply_button(object.ap_id) }}
     </div>