diff --git a/lib/api/api.rb b/lib/api/api.rb
index 3d7d67510a83ac12c19114400671e8b5f2c70e26..f18258bf5a3669806080f963c31af71d3ef9e881 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -26,6 +26,7 @@ module API
     # Ensure the namespace is right, otherwise we might load Grape::API::Helpers
     helpers ::API::Helpers
 
+    mount ::API::Artifacts
     mount ::API::AwardEmoji
     mount ::API::Branches
     mount ::API::Builds
diff --git a/lib/api/artifacts.rb b/lib/api/artifacts.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6ce2bed8260e9a639a6b42dcf879a303afc83938
--- /dev/null
+++ b/lib/api/artifacts.rb
@@ -0,0 +1,34 @@
+module API
+  # Projects artifacts API
+  class Artifacts < Grape::API
+    before do
+      authenticate!
+      authorize!(:read_build, user_project)
+    end
+
+    resource :projects do
+      # Download the artifacts file from ref_name and build_name
+      #
+      # Parameters:
+      #   id (required) - The ID of a project
+      #   ref_name (required) - The ref from repository
+      #   build_name (required) - The name for the build
+      # Example Request:
+      #   GET /projects/:id/artifacts/:ref_name/:build_name
+      get ':id/artifacts/:ref_name/:build_name',
+          requirements: { ref_name: /.+/ } do
+        builds = user_project.builds_for(
+          params[:build_name], params[:ref_name])
+
+        latest_build = builds.success.latest.first
+
+        if latest_build
+          redirect(
+            "/projects/#{user_project.id}/builds/#{latest_build.id}/artifacts")
+        else
+          not_found!
+        end
+      end
+    end
+  end
+end
diff --git a/spec/requests/api/artifacts_spec.rb b/spec/requests/api/artifacts_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..2b84c1a2072f3fb89f62eec9b136510a531ccac9
--- /dev/null
+++ b/spec/requests/api/artifacts_spec.rb
@@ -0,0 +1,52 @@
+require 'spec_helper'
+require_relative '../shared/artifacts_context'
+
+describe API::API, api: true  do
+  include ApiHelpers
+
+  let(:user) { create(:user) }
+  let(:project) { create(:project) }
+  let(:pipeline) do
+    create(:ci_pipeline, project: project, sha: project.commit('fix').sha)
+  end
+  let(:build) { create(:ci_build, :success, :artifacts, pipeline: pipeline) }
+
+  before do
+    project.team << [user, :developer]
+  end
+
+  describe 'GET /projects/:id/artifacts/:ref_name/:build_name' do
+    def path_from_ref(ref = pipeline.sha, build_name = build.name, _ = '')
+      api("/projects/#{project.id}/artifacts/#{ref}/#{build_name}", user)
+    end
+
+    context '401' do
+      let(:user) { nil }
+
+      before do
+        get path_from_ref
+      end
+
+      it 'gives 401 for unauthorized user' do
+        expect(response).to have_http_status(401)
+      end
+    end
+
+    context '404' do
+      def verify
+        expect(response).to have_http_status(404)
+      end
+
+      it_behaves_like 'artifacts from ref with 404'
+    end
+
+    context '302' do
+      def verify
+        expect(response).to redirect_to(
+          "/projects/#{project.id}/builds/#{build.id}/artifacts")
+      end
+
+      it_behaves_like 'artifacts from ref with 302'
+    end
+  end
+end
diff --git a/spec/requests/projects/artifacts_controller_spec.rb b/spec/requests/projects/artifacts_controller_spec.rb
index 4c4bacfcbda4dcd6b58ad6b40a9e0c19becdeb25..9722a9a1d64f671c6fb43f71b8623ba3bd8ba8b3 100644
--- a/spec/requests/projects/artifacts_controller_spec.rb
+++ b/spec/requests/projects/artifacts_controller_spec.rb
@@ -1,4 +1,5 @@
 require 'spec_helper'
+require_relative '../shared/artifacts_context'
 
 describe Projects::ArtifactsController do
   let(:user) { create(:user) }
@@ -14,120 +15,43 @@ describe Projects::ArtifactsController do
   end
 
   describe 'GET /:project/artifacts/:ref/:build_name/browse' do
-    context '404' do
-      it 'has no such ref' do
-        get search_namespace_project_artifacts_path(
-          project.namespace,
-          project,
-          'TAIL',
-          build.name,
-          'browse')
+    def path_from_ref(ref = pipeline.sha, build_name = build.name,
+                      path = 'browse')
+      search_namespace_project_artifacts_path(
+        project.namespace,
+        project,
+        ref,
+        build_name,
+        path)
+    end
 
+    context '404' do
+      def verify
         expect(response.status).to eq(404)
       end
 
-      it 'has no such build' do
-        get search_namespace_project_artifacts_path(
-          project.namespace,
-          project,
-          pipeline.sha,
-          'NOBUILD',
-          'browse')
-
-        expect(response.status).to eq(404)
-      end
+      it_behaves_like 'artifacts from ref with 404'
 
-      it 'has no path' do
-        get search_namespace_project_artifacts_path(
-          project.namespace,
-          project,
-          pipeline.sha,
-          build.name,
-          '')
+      context 'has no path' do
+        before do
+          get path_from_ref(pipeline.sha, build.name, '')
+        end
 
-        expect(response.status).to eq(404)
+        it('gives 404') { verify }
       end
     end
 
     context '302' do
-      def path_from_ref(ref = pipeline.sha, build_name = build.name)
-        search_namespace_project_artifacts_path(
+      def verify
+        path = browse_namespace_project_build_artifacts_path(
           project.namespace,
           project,
-          ref,
-          build_name,
-          'browse')
-      end
-
-      shared_examples 'redirect to the build' do
-        it 'redirects' do
-          path = browse_namespace_project_build_artifacts_path(
-            project.namespace,
-            project,
-            build)
-
-          expect(response).to redirect_to(path)
-        end
-      end
-
-      context 'with sha' do
-        before do
-          get path_from_ref
-        end
-
-        it_behaves_like 'redirect to the build'
-      end
-
-      context 'with regular branch' do
-        before do
-          pipeline.update(sha: project.commit('master').sha)
-        end
-
-        before do
-          get path_from_ref('master')
-        end
-
-        it_behaves_like 'redirect to the build'
-      end
-
-      context 'with branch name containing slash' do
-        before do
-          pipeline.update(sha: project.commit('improve/awesome').sha)
-        end
+          build)
 
-        before do
-          get path_from_ref('improve/awesome')
-        end
-
-        it_behaves_like 'redirect to the build'
+        expect(response).to redirect_to(path)
       end
 
-      context 'with latest build' do
-        before do
-          3.times do # creating some old builds
-            create(:ci_build, :success, :artifacts, pipeline: pipeline)
-          end
-        end
-
-        before do
-          get path_from_ref
-        end
-
-        it_behaves_like 'redirect to the build'
-      end
-
-      context 'with success build' do
-        before do
-          build # make sure build was old, but still the latest success one
-          create(:ci_build, :pending, :artifacts, pipeline: pipeline)
-        end
-
-        before do
-          get path_from_ref
-        end
-
-        it_behaves_like 'redirect to the build'
-      end
+      it_behaves_like 'artifacts from ref with 302'
     end
   end
 end
diff --git a/spec/requests/shared/artifacts_context.rb b/spec/requests/shared/artifacts_context.rb
new file mode 100644
index 0000000000000000000000000000000000000000..4333be6e1cd680eb4c24d2eebbcd1a2730a4f7de
--- /dev/null
+++ b/spec/requests/shared/artifacts_context.rb
@@ -0,0 +1,78 @@
+shared_context 'artifacts from ref with 404' do
+  context 'has no such ref' do
+    before do
+      get path_from_ref('TAIL', build.name)
+    end
+
+    it('gives 404') { verify }
+  end
+
+  context 'has no such build' do
+    before do
+      get path_from_ref(pipeline.sha, 'NOBUILD')
+    end
+
+    it('gives 404') { verify }
+  end
+end
+
+shared_context 'artifacts from ref with 302' do
+  context 'with sha' do
+    before do
+      get path_from_ref
+    end
+
+    it('redirects') { verify }
+  end
+
+  context 'with regular branch' do
+    before do
+      pipeline.update(sha: project.commit('master').sha)
+    end
+
+    before do
+      get path_from_ref('master')
+    end
+
+    it('redirects') { verify }
+  end
+
+  context 'with branch name containing slash' do
+    before do
+      pipeline.update(sha: project.commit('improve/awesome').sha)
+    end
+
+    before do
+      get path_from_ref('improve/awesome')
+    end
+
+    it('redirects') { verify }
+  end
+
+  context 'with latest build' do
+    before do
+      3.times do # creating some old builds
+        create(:ci_build, :success, :artifacts, pipeline: pipeline)
+      end
+    end
+
+    before do
+      get path_from_ref
+    end
+
+    it('redirects') { verify }
+  end
+
+  context 'with success build' do
+    before do
+      build # make sure build was old, but still the latest success one
+      create(:ci_build, :pending, :artifacts, pipeline: pipeline)
+    end
+
+    before do
+      get path_from_ref
+    end
+
+    it('redirects') { verify }
+  end
+end