diff --git a/CHANGELOG b/CHANGELOG
index 2d16f7fd3abd48a03ae68826f78a8a9eb324e6c4..e478e8c3365b2a9ea58beeaf618f2c00f0b256d4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -73,6 +73,7 @@ v 8.13.0 (unreleased)
   - Add disabled delete button to protected branches (ClemMakesApps)
   - Add broadcast messages and alerts below sub-nav
   - Better empty state for Groups view
+  - API: New /users/:id/events endpoint
   - Update ruby-prof to 0.16.2. !6026 (Elan Ruusamäe)
   - Replace bootstrap caret with fontawesome caret (ClemMakesApps)
   - Fix unnecessary escaping of reserved HTML characters in milestone title. !6533
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 27436a052daa2f0413af21d9ffa3e1fb1eb15c06..f96bf7f6d63f0277b176b4e43caa229fdeb2f688 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -436,7 +436,7 @@ Parameters:
 ### Get project events
 
 Get the events for the specified project.
-Sorted from newest to latest
+Sorted from newest to oldest
 
 ```
 GET /projects/:id/events
diff --git a/doc/api/users.md b/doc/api/users.md
index 9be4f2e6ec32c4964664b744c2b5ed781ad7922c..a52b2d51d78118b07e2ef6daebc474ecacbf70a2 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -627,3 +627,149 @@ Parameters:
 
 Will return `200 OK` on success, `404 User Not Found` is user cannot be found or
 `403 Forbidden` when trying to unblock a user blocked by LDAP synchronization.
+
+### Get user contribution events
+
+Get the contribution events for the specified user, sorted from newest to oldest.
+
+```
+GET /users/:id/events
+```
+
+Parameters:
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `id` | integer | yes | The ID of the user |
+
+```bash
+curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/user/:id/events
+```
+
+Example response:
+
+```json
+[
+  {
+    "title": null,
+    "project_id": 15,
+    "action_name": "closed",
+    "target_id": 830,
+    "target_type": "Issue",
+    "author_id": 1,
+    "data": null,
+    "target_title": "Public project search field",
+    "author": {
+      "name": "Dmitriy Zaporozhets",
+      "username": "root",
+      "id": 1,
+      "state": "active",
+      "avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
+      "web_url": "http://localhost:3000/u/root"
+    },
+    "author_username": "root"
+  },
+  {
+    "title": null,
+    "project_id": 15,
+    "action_name": "opened",
+    "target_id": null,
+    "target_type": null,
+    "author_id": 1,
+    "author": {
+      "name": "Dmitriy Zaporozhets",
+      "username": "root",
+      "id": 1,
+      "state": "active",
+      "avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
+      "web_url": "http://localhost:3000/u/root"
+    },
+    "author_username": "john",
+    "data": {
+      "before": "50d4420237a9de7be1304607147aec22e4a14af7",
+      "after": "c5feabde2d8cd023215af4d2ceeb7a64839fc428",
+      "ref": "refs/heads/master",
+      "user_id": 1,
+      "user_name": "Dmitriy Zaporozhets",
+      "repository": {
+        "name": "gitlabhq",
+        "url": "git@dev.gitlab.org:gitlab/gitlabhq.git",
+        "description": "GitLab: self hosted Git management software. \r\nDistributed under the MIT License.",
+        "homepage": "https://dev.gitlab.org/gitlab/gitlabhq"
+      },
+      "commits": [
+        {
+          "id": "c5feabde2d8cd023215af4d2ceeb7a64839fc428",
+          "message": "Add simple search to projects in public area",
+          "timestamp": "2013-05-13T18:18:08+00:00",
+          "url": "https://dev.gitlab.org/gitlab/gitlabhq/commit/c5feabde2d8cd023215af4d2ceeb7a64839fc428",
+          "author": {
+            "name": "Dmitriy Zaporozhets",
+            "email": "dmitriy.zaporozhets@gmail.com"
+          }
+        }
+      ],
+      "total_commits_count": 1
+    },
+    "target_title": null
+  },
+  {
+    "title": null,
+    "project_id": 15,
+    "action_name": "closed",
+    "target_id": 840,
+    "target_type": "Issue",
+    "author_id": 1,
+    "data": null,
+    "target_title": "Finish & merge Code search PR",
+    "author": {
+      "name": "Dmitriy Zaporozhets",
+      "username": "root",
+      "id": 1,
+      "state": "active",
+      "avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
+      "web_url": "http://localhost:3000/u/root"
+    },
+    "author_username": "root"
+  },
+  {
+    "title": null,
+    "project_id": 15,
+    "action_name": "commented on",
+    "target_id": 1312,
+    "target_type": "Note",
+    "author_id": 1,
+    "data": null,
+    "target_title": null,
+    "created_at": "2015-12-04T10:33:58.089Z",
+    "note": {
+      "id": 1312,
+      "body": "What an awesome day!",
+      "attachment": null,
+      "author": {
+        "name": "Dmitriy Zaporozhets",
+        "username": "root",
+        "id": 1,
+        "state": "active",
+        "avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
+        "web_url": "http://localhost:3000/u/root"
+      },
+      "created_at": "2015-12-04T10:33:56.698Z",
+      "system": false,
+      "upvote": false,
+      "downvote": false,
+      "noteable_id": 377,
+      "noteable_type": "Issue"
+    },
+    "author": {
+      "name": "Dmitriy Zaporozhets",
+      "username": "root",
+      "id": 1,
+      "state": "active",
+      "avatar_url": "http://localhost:3000/uploads/user/avatar/1/fox_avatar.png",
+      "web_url": "http://localhost:3000/u/root"
+    },
+    "author_username": "root"
+  }
+]
+```
diff --git a/lib/api/users.rb b/lib/api/users.rb
index 18c4cad09ae0f68cd5161178c210b8389a5c4a99..e868f628404d147ded45db313115dfe1c36f5ac0 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -321,6 +321,26 @@ class Users < Grape::API
           user.activate
         end
       end
+
+      desc 'Get contribution events of a specified user' do
+        detail 'This feature was introduced in GitLab 8.13.'
+        success Entities::Event
+      end
+      params do
+        requires :id, type: String, desc: 'The user ID'
+      end
+      get ':id/events' do
+        user = User.find_by(id: declared(params).id)
+        not_found!('User') unless user
+
+        events = user.recent_events.
+          merge(ProjectsFinder.new.execute(current_user)).
+          references(:project).
+          with_associations.
+          page(params[:page])
+
+        present paginate(events), with: Entities::Event
+      end
     end
 
     resource :user do
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index b002949b41b291fcc29ee3e697266fe8946156c1..f83f4d2c9b1d302dfba65463d71a0b73cf6a2019 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -913,4 +913,58 @@
       expect(response).to have_http_status(404)
     end
   end
+
+  describe 'GET /user/:id/events' do
+    let(:user) { create(:user) }
+    let(:project) { create(:empty_project) }
+    let(:note) { create(:note_on_issue, note: 'What an awesome day!', project: project) }
+
+    before do
+      project.add_user(user, :developer)
+      EventCreateService.new.leave_note(note, user)
+    end
+
+    context "as a user than cannot see the event's project" do
+      it 'returns no events' do
+        other_user = create(:user)
+
+        get api("/users/#{user.id}/events", other_user)
+
+        expect(response).to have_http_status(200)
+        expect(json_response).to be_empty
+      end
+    end
+
+    context "as a user than can see the event's project" do
+      it_behaves_like 'a paginated resources' do
+        let(:request) { get api("/users/#{user.id}/events", user) }
+      end
+
+      context 'joined event' do
+        it 'returns the "joined" event' do
+          get api("/users/#{user.id}/events", user)
+
+          comment_event = json_response.find { |e| e['action_name'] == 'commented on' }
+
+          expect(comment_event['project_id'].to_i).to eq(project.id)
+          expect(comment_event['author_username']).to eq(user.username)
+          expect(comment_event['note']['id']).to eq(note.id)
+          expect(comment_event['note']['body']).to eq('What an awesome day!')
+
+          joined_event = json_response.find { |e| e['action_name'] == 'joined' }
+
+          expect(joined_event['project_id'].to_i).to eq(project.id)
+          expect(joined_event['author_username']).to eq(user.username)
+          expect(joined_event['author']['name']).to eq(user.name)
+        end
+      end
+    end
+
+    it 'returns a 404 error if not found' do
+      get api('/users/42/events', user)
+
+      expect(response).to have_http_status(404)
+      expect(json_response['message']).to eq('404 User Not Found')
+    end
+  end
 end