diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 47ab4e1aab08f07c031b5ebff4dc42ad5385353a..e6df6b4ee88d4a9d07d3c8ce70e76cbe63703d3d 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -89,15 +89,26 @@ module Gitlab
       #   POST /projects/:id/members
       post ":id/members" do
         authorize! :admin_project, user_project
-        users_project = user_project.users_projects.new(
-          user_id: params[:user_id],
-          project_access: params[:access_level]
-        )
 
-        if users_project.save
-          @member = users_project.user
+        error!("User id not given", 400) if !params.has_key? :user_id
+        error!("Access level not given", 400) if !params.has_key? :access_level
+
+        # either the user is already a team member or a new one
+        team_member = user_project.team_member_by_id(params[:user_id])
+        if team_member.nil?
+          team_member = user_project.users_projects.new(
+            user_id: params[:user_id],
+            project_access: params[:access_level]
+          )
+        end
+
+        if team_member.save
+          @member = team_member.user
           present @member, with: Entities::ProjectMember, project: user_project
         else
+          if team_member.errors[:project_access].any?
+            error!(team_member.errors[:project_access], 422)
+          end
           not_found!
         end
       end
@@ -112,12 +123,18 @@ module Gitlab
       #   PUT /projects/:id/members/:user_id
       put ":id/members/:user_id" do
         authorize! :admin_project, user_project
-        users_project = user_project.users_projects.find_by_user_id params[:user_id]
 
-        if users_project.update_attributes(project_access: params[:access_level])
-          @member = users_project.user
+        team_member = user_project.users_projects.find_by_user_id(params[:user_id])
+        error!("Access level not given", 400) if !params.has_key? :access_level
+        error!("User can not be found", 404) if team_member.nil?
+
+        if team_member.update_attributes(project_access: params[:access_level])
+          @member = team_member.user
           present @member, with: Entities::ProjectMember, project: user_project
         else
+          if team_member.errors[:project_access].any?
+            error!(team_member.errors[:project_access], 422)
+          end
           not_found!
         end
       end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 2682629e7db5d9f4b7f54400e6a2ff2c333e245c..91632407c6f2bfc87fa4e87a0fc2ec547ac841e3 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -177,6 +177,34 @@ describe Gitlab::API do
       json_response['email'].should == user2.email
       json_response['access_level'].should == UsersProject::DEVELOPER
     end
+
+    it "should return a 201 status if user is already project member" do
+      post api("/projects/#{project.id}/members", user), user_id: user2.id,
+        access_level: UsersProject::DEVELOPER
+      expect {
+        post api("/projects/#{project.id}/members", user), user_id: user2.id,
+          access_level: UsersProject::DEVELOPER
+      }.not_to change { UsersProject.count }.by(1)
+
+      response.status.should == 201
+      json_response['email'].should == user2.email
+      json_response['access_level'].should == UsersProject::DEVELOPER
+    end
+
+    it "should return a 400 error when user id is not given" do
+      post api("/projects/#{project.id}/members", user), access_level: UsersProject::MASTER
+      response.status.should == 400
+    end
+
+    it "should return a 400 error when access level is not given" do
+      post api("/projects/#{project.id}/members", user), user_id: user2.id
+      response.status.should == 400
+    end
+
+    it "should return a 422 error when access level is not known" do
+      post api("/projects/#{project.id}/members", user), user_id: user2.id, access_level: 1234
+      response.status.should == 422
+    end
   end
 
   describe "PUT /projects/:id/members/:user_id" do
@@ -186,6 +214,21 @@ describe Gitlab::API do
       json_response['email'].should == user3.email
       json_response['access_level'].should == UsersProject::MASTER
     end
+
+    it "should return a 404 error if user_id is not found" do
+      put api("/projects/#{project.id}/members/1234", user), access_level: UsersProject::MASTER
+      response.status.should == 404
+    end
+
+    it "should return a 400 error when access level is not given" do
+      put api("/projects/#{project.id}/members/#{user3.id}", user)
+      response.status.should == 400
+    end
+
+    it "should return a 422 error when access level is not known" do
+      put api("/projects/#{project.id}/members/#{user3.id}", user), access_level: 123
+      response.status.should == 422
+    end
   end
 
   describe "DELETE /projects/:id/members/:user_id" do