diff --git a/src/controllers/groups_controller.rs b/src/controllers/groups_controller.rs
index 5dcbd1f..f32949e 100644
--- a/src/controllers/groups_controller.rs
+++ b/src/controllers/groups_controller.rs
@@ -172,4 +172,24 @@ pub fn invite_user(r: &mut HttpRequestHandler) -> RequestResult {
     // TODO : send a notification
 
     r.success("The user has been successfully invited to join the group!")
+}
+
+/// Respond to a user invitation
+pub fn respond_invitation(r: &mut HttpRequestHandler) -> RequestResult {
+    let group_id = r.post_group_id_with_access("id", GroupAccessLevel::LIMITED_ACCESS)?;
+    let accept = r.post_bool("accept")?;
+
+    if !groups_helper::received_invitation(&group_id, &r.user_id()?)? {
+        r.not_found("Invitation not found!".to_string())?
+    }
+
+    groups_helper::respond_invitation(&group_id, &r.user_id()?, accept)?;
+
+    if accept {
+        groups_helper::set_following(&group_id, &r.user_id()?, true)?;
+    }
+
+    // TODO : Create a notification
+
+    r.success("Response to the invitation was successfully saved!")
 }
\ No newline at end of file
diff --git a/src/controllers/routes.rs b/src/controllers/routes.rs
index cc54029..62b2640 100644
--- a/src/controllers/routes.rs
+++ b/src/controllers/routes.rs
@@ -152,6 +152,8 @@ pub fn get_routes() -> Vec<Route> {
 
         Route::post("/groups/invite", Box::new(groups_controller::invite_user)),
 
+        Route::post("/groups/respond_invitation", Box::new(groups_controller::respond_invitation)),
+
 
         // Virtual directory controller
         Route::post("/user/findbyfolder", Box::new(virtual_directory_controller::find_user)),
diff --git a/src/helpers/database.rs b/src/helpers/database.rs
index a9633df..b95bcde 100644
--- a/src/helpers/database.rs
+++ b/src/helpers/database.rs
@@ -616,6 +616,11 @@ impl DeleteQuery {
         self
     }
 
+    pub fn cond_group_id(mut self, key: &str, value: &GroupID) -> DeleteQuery {
+        self.conditions.insert(key.to_string(), Value::from(value.id()));
+        self
+    }
+
     /// Execute the delete query
     pub fn exec(self) -> ResultBoxError<()> {
         delete(self)
diff --git a/src/helpers/groups_helper.rs b/src/helpers/groups_helper.rs
index ad175a3..bdff711 100644
--- a/src/helpers/groups_helper.rs
+++ b/src/helpers/groups_helper.rs
@@ -125,6 +125,32 @@ pub fn insert_member(m: &GroupMember) -> ResultBoxError<()> {
         .insert_drop_result()
 }
 
+/// Remove a user's membership
+pub fn delete_member(group_id: &GroupID, user_id: &UserID) -> ResultBoxError {
+    database::DeleteQuery::new(GROUPS_MEMBERS_TABLE)
+        .cond_group_id("groups_id", group_id)
+        .cond_user_id("user_id", user_id)
+        .exec()
+}
+
+/// Update a user's membership level
+pub fn update_membership_level(group_id: &GroupID, user_id: &UserID, new_level: GroupMembershipLevel) -> ResultBoxError {
+    database::UpdateInfo::new(GROUPS_MEMBERS_TABLE)
+        .cond_user_id("user_id", user_id)
+        .cond_group_id("groups_id", group_id)
+        .set_u32("level", new_level.to_db())
+        .exec()
+}
+
+/// Update following status of a user
+pub fn set_following(g: &GroupID, u: &UserID, follow: bool) -> ResultBoxError {
+    database::UpdateInfo::new(GROUPS_MEMBERS_TABLE)
+        .cond_group_id("groups_id", g)
+        .cond_user_id("user_id", u)
+        .set_legacy_bool("following", follow)
+        .exec()
+}
+
 /// Get the list of groups of a user
 pub fn get_list_user(user_id: UserID, only_followed: bool) -> ResultBoxError<Vec<GroupID>> {
     let mut query = database::QueryInfo::new(GROUPS_MEMBERS_TABLE)
@@ -343,6 +369,24 @@ pub fn send_invitation(group_id: &GroupID, user_id: &UserID) -> ResultBoxError {
     })
 }
 
+/// Check out whether a user received an invitation to join a group or not
+pub fn received_invitation(group_id: &GroupID, user_id: &UserID) -> ResultBoxError<bool> {
+    database::QueryInfo::new(GROUPS_MEMBERS_TABLE)
+        .cond_group_id("groups_id", group_id)
+        .cond_user_id("user_ID", user_id)
+        .cond_u32("level", GroupMembershipLevel::INVITED.to_db())
+        .exec_count()
+        .map(|f| f > 0)
+}
+
+/// Respond to a group membership invitation
+pub fn respond_invitation(g: &GroupID, u: &UserID, accept: bool) -> ResultBoxError {
+    match accept {
+        true => update_membership_level(g, u, GroupMembershipLevel::MEMBER),
+        false => delete_member(g, u),
+    }
+}
+
 /// Turn a database entry into a group struct
 fn db_to_group(row: &database::RowResult) -> ResultBoxError<Group> {
     let group_id = row.get_group_id("id")?;