diff --git a/src/routes/guild.rs b/src/routes/guild.rs
index ee79711f34159dd8a3d045295a630616ffc33ff0..e44b3daa3f77d05e8bcc076bef3d3a8bbfff2bb0 100644
--- a/src/routes/guild.rs
+++ b/src/routes/guild.rs
@@ -129,6 +129,98 @@ pub fn guild(user: UserRef, target: GuildRef) -> Option<Response> {
     }
 }
 
+/// delete or leave a guild
+#[delete("/<target>")]
+pub fn remove_guild(user: UserRef, target: GuildRef) -> Option<Response> {
+    with_permissions!(user, target);
+
+    if user.id == target.owner {
+        let channels = database::get_collection("channels");
+        if let Ok(result) = channels.find(
+            doc! {
+                "type": 2,
+                "guild": &target.id
+            },
+            FindOptions::builder().projection(doc! { "_id": 1 }).build(),
+        ) {
+            let mut values = vec![];
+            for item in result {
+                if let Ok(doc) = item {
+                    values.push(Bson::String(doc.get_str("_id").unwrap().to_string()));
+                }
+            }
+
+            if database::get_collection("messages")
+                .delete_many(
+                    doc! {
+                        "channel": {
+                            "$in": values
+                        }
+                    },
+                    None,
+                )
+                .is_ok()
+            {
+                if channels
+                    .delete_many(
+                        doc! {
+                            "type": 2,
+                            "guild": &target.id,
+                        },
+                        None,
+                    )
+                    .is_ok()
+                {
+                    if database::get_collection("guilds")
+                        .delete_one(
+                            doc! {
+                                "_id": &target.id
+                            },
+                            None,
+                        )
+                        .is_ok()
+                    {
+                        Some(Response::Result(super::Status::Ok))
+                    } else {
+                        Some(Response::InternalServerError(
+                            json!({ "error": "Failed to delete guild." }),
+                        ))
+                    }
+                } else {
+                    Some(Response::InternalServerError(
+                        json!({ "error": "Failed to delete guild channels." }),
+                    ))
+                }
+            } else {
+                Some(Response::InternalServerError(
+                    json!({ "error": "Failed to delete guild messages." }),
+                ))
+            }
+        } else {
+            Some(Response::InternalServerError(
+                json!({ "error": "Could not fetch channels." }),
+            ))
+        }
+    } else {
+        if database::get_collection("members")
+            .delete_one(
+                doc! {
+                    "_id.guild": &target.id,
+                    "_id.user": &user.id,
+                },
+                None,
+            )
+            .is_ok()
+        {
+            Some(Response::Result(super::Status::Ok))
+        } else {
+            Some(Response::InternalServerError(
+                json!({ "error": "Failed to remove you from the guild." }),
+            ))
+        }
+    }
+}
+
 #[derive(Serialize, Deserialize)]
 pub struct CreateChannel {
     nonce: String,
diff --git a/src/routes/mod.rs b/src/routes/mod.rs
index c847d799a5e355d256021dbf79f7b4e9c05f2b3e..2493df4fd4cd77b04083fa33d62effb59b2f88b6 100644
--- a/src/routes/mod.rs
+++ b/src/routes/mod.rs
@@ -106,6 +106,7 @@ pub fn mount(rocket: Rocket) -> Rocket {
             routes![
                 guild::my_guilds,
                 guild::guild,
+                guild::remove_guild,
                 guild::create_channel,
                 guild::create_invite,
                 guild::remove_invite,