diff --git a/services/backup/src/database/mod.rs b/services/backup/src/database/mod.rs
--- a/services/backup/src/database/mod.rs
+++ b/services/backup/src/database/mod.rs
@@ -306,6 +306,24 @@
 
 // general functions
 impl DatabaseClient {
+  pub async fn delete_user_data(
+    &self,
+    user_id: &str,
+    blob_client: &BlobServiceClient,
+  ) -> Result<(), Error> {
+    // query the index to avoid unnecessarily querying backup data
+    let items = self.query_ordered_backups_index(user_id, None).await?;
+
+    for item in items {
+      trace!("Removing backup item: {item:?}");
+      self
+        .remove_backup_item(user_id, &item.backup_id, blob_client)
+        .await?;
+    }
+
+    Ok(())
+  }
+
   async fn query_ordered_backups_index(
     &self,
     user_id: &str,
diff --git a/services/backup/src/http/handlers/user_data.rs b/services/backup/src/http/handlers/user_data.rs
new file mode 100644
--- /dev/null
+++ b/services/backup/src/http/handlers/user_data.rs
@@ -0,0 +1,38 @@
+use actix_web::{
+  error::ErrorForbidden,
+  web::{self},
+  HttpResponse,
+};
+use comm_lib::{
+  auth::AuthorizationCredential, blob::client::BlobServiceClient,
+  http::auth_service::Authenticated,
+};
+use tracing::{info, instrument};
+
+use crate::{database::DatabaseClient, error::BackupError};
+
+#[instrument(skip_all, fields(backup_id = %path))]
+pub async fn delete_user_data(
+  requesting_identity: AuthorizationCredential,
+  path: web::Path<String>,
+  db_client: web::Data<DatabaseClient>,
+  blob_client: Authenticated<BlobServiceClient>,
+) -> actix_web::Result<HttpResponse> {
+  match requesting_identity {
+    AuthorizationCredential::ServicesToken(_) => (),
+    _ => {
+      return Err(ErrorForbidden(
+        "This endpoint can only be called by other services",
+      ));
+    }
+  };
+
+  info!("Delete user data request");
+  let user_id = path.into_inner();
+  db_client
+    .delete_user_data(&user_id, &blob_client)
+    .await
+    .map_err(BackupError::from)?;
+
+  Ok(HttpResponse::NoContent().finish())
+}
diff --git a/services/backup/src/http/mod.rs b/services/backup/src/http/mod.rs
--- a/services/backup/src/http/mod.rs
+++ b/services/backup/src/http/mod.rs
@@ -11,6 +11,7 @@
 mod handlers {
   pub(super) mod backup;
   pub(super) mod log;
+  pub(super) mod user_data;
 }
 
 pub async fn run_http_server(
@@ -67,6 +68,14 @@
         web::scope("/logs")
           .service(web::resource("").route(web::get().to(handle_ws))),
       )
+      .service(
+        web::scope("/user_data")
+          .wrap(get_comm_authentication_middleware())
+          .service(
+            web::resource("{user_id}")
+              .route(web::delete().to(handlers::user_data::delete_user_data)),
+          ),
+      )
   })
   .bind(("0.0.0.0", CONFIG.http_port))?
   .run()