diff --git a/app/models/repository.rb b/app/models/repository.rb
index 063dc74021d5ce5f04a2b85bef9998980fb7aff5..4282197faa5f661518e305075841b0c458c8a7a5 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -631,7 +631,7 @@ class Repository
     @head_tree ||= Tree.new(self, head_commit.sha, nil)
   end
 
-  def tree(sha = :head, path = nil)
+  def tree(sha = :head, path = nil, recursive: false)
     if sha == :head
       if path.nil?
         return head_tree
@@ -640,7 +640,7 @@ class Repository
       end
     end
 
-    Tree.new(self, sha, path)
+    Tree.new(self, sha, path, recursive: recursive)
   end
 
   def blob_at_branch(branch_name, path)
diff --git a/app/models/tree.rb b/app/models/tree.rb
index 7c4ed6e393b907a7b8e2298b24b164ab74dd0fc1..2d1d68dbd815de8986dc9ea0defef3405d2e5e23 100644
--- a/app/models/tree.rb
+++ b/app/models/tree.rb
@@ -3,15 +3,16 @@ class Tree
 
   attr_accessor :repository, :sha, :path, :entries
 
-  def initialize(repository, sha, path = '/')
+  def initialize(repository, sha, path = '/', recursive: false)
     path = '/' if path.blank?
 
     @repository = repository
     @sha = sha
     @path = path
+    @recursive = recursive
 
     git_repo = @repository.raw_repository
-    @entries = Gitlab::Git::Tree.where(git_repo, @sha, @path)
+    @entries = get_entries(git_repo, @sha, @path, recursive: @recursive)
   end
 
   def readme
@@ -58,4 +59,21 @@ class Tree
   def sorted_entries
     trees + blobs + submodules
   end
+
+  private
+
+  def get_entries(git_repo, sha, path, recursive: false)
+    current_path_entries = Gitlab::Git::Tree.where(git_repo, sha, path)
+    ordered_entries = []
+
+    current_path_entries.each do |entry|
+      ordered_entries << entry
+
+      if recursive && entry.dir?
+        ordered_entries.concat(get_entries(git_repo, sha, entry.path, recursive: true))
+      end
+    end
+
+    ordered_entries
+  end
 end
diff --git a/changelogs/unreleased/master-recursiveTree.yml b/changelogs/unreleased/master-recursiveTree.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c6384d172e27a02df8ae290968ff6cb16243e2fd
--- /dev/null
+++ b/changelogs/unreleased/master-recursiveTree.yml
@@ -0,0 +1,4 @@
+---
+title: API: allow recursive tree request
+merge_request: 6088
+author: Rebeca Méndez
diff --git a/doc/api/repositories.md b/doc/api/repositories.md
index b6cca5d4e2ad6892a00c8bc11503d8738a68fa8d..bcf8b955044520ac0bbb22ecba556e18a9ad739d 100644
--- a/doc/api/repositories.md
+++ b/doc/api/repositories.md
@@ -13,44 +13,58 @@ Parameters:
 - `id` (required) - The ID of a project
 - `path` (optional) - The path inside repository. Used to get contend of subdirectories
 - `ref_name` (optional) - The name of a repository branch or tag or if not given the default branch
+- `recursive` (optional) - Boolean value used to get a recursive tree (false by default)
 
 ```json
 [
   {
-    "name": "assets",
+    "id": "a1e8f8d745cc87e3a9248358d9352bb7f9a0aeba",
+    "name": "html",
     "type": "tree",
-    "mode": "040000",
-    "id": "6229c43a7e16fcc7e95f923f8ddadb8281d9c6c6"
+    "path": "files/html",
+    "mode": "040000"
   },
   {
-    "name": "contexts",
+    "id": "4535904260b1082e14f867f7a24fd8c21495bde3",
+    "name": "images",
     "type": "tree",
-    "mode": "040000",
-    "id": "faf1cdf33feadc7973118ca42d35f1e62977e91f"
+    "path": "files/images",
+    "mode": "040000"
   },
   {
-    "name": "controllers",
+    "id": "31405c5ddef582c5a9b7a85230413ff90e2fe720",
+    "name": "js",
     "type": "tree",
-    "mode": "040000",
-    "id": "95633e8d258bf3dfba3a5268fb8440d263218d74"
+    "path": "files/js",
+    "mode": "040000"
   },
   {
-    "name": "Rakefile",
-    "type": "blob",
-    "mode": "100644",
-    "id": "35b2f05cbb4566b71b34554cf184a9d0bd9d46d6"
+    "id": "cc71111cfad871212dc99572599a568bfe1e7e00",
+    "name": "lfs",
+    "type": "tree",
+    "path": "files/lfs",
+    "mode": "040000"
   },
   {
-    "name": "VERSION",
-    "type": "blob",
-    "mode": "100644",
-    "id": "803e4a4f3727286c3093c63870c2b6524d30ec4f"
+    "id": "fd581c619bf59cfdfa9c8282377bb09c2f897520",
+    "name": "markdown",
+    "type": "tree",
+    "path": "files/markdown",
+    "mode": "040000"
+  },
+  {
+    "id": "23ea4d11a4bdd960ee5320c5cb65b5b3fdbc60db",
+    "name": "ruby",
+    "type": "tree",
+    "path": "files/ruby",
+    "mode": "040000"
   },
   {
-    "name": "config.ru",
+    "id": "7d70e02340bac451f281cecf0a980907974bd8be",
+    "name": "whitespace",
     "type": "blob",
-    "mode": "100644",
-    "id": "dfd2d862237323aa599be31b473d70a8a817943b"
+    "path": "files/whitespace",
+    "mode": "100644"
   }
 ]
 ```
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 1942aeea6566277fbb093f2650b611d9d0d70c10..8f1aaaaaaa0140d0e2f4dfd3954cc520614697ab 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -159,7 +159,7 @@ module API
     end
 
     class RepoTreeObject < Grape::Entity
-      expose :id, :name, :type
+      expose :id, :name, :type, :path
 
       expose :mode do |obj, options|
         filemode = obj.mode.to_s(8)
diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb
index f55aceed92c357cb9f97ccd9f4090a6cc574612d..0bb2f74809a35f48d86101aed5709a3a595eeff8 100644
--- a/lib/api/repositories.rb
+++ b/lib/api/repositories.rb
@@ -21,16 +21,18 @@ module API
       # Parameters:
       #   id (required) - The ID of a project
       #   ref_name (optional) - The name of a repository branch or tag, if not given the default branch is used
+      #   recursive (optional) - Used to get a recursive tree
       # Example Request:
       #   GET /projects/:id/repository/tree
       get ':id/repository/tree' do
         ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
         path = params[:path] || nil
+        recursive = to_boolean(params[:recursive])
 
         commit = user_project.commit(ref)
         not_found!('Tree') unless commit
 
-        tree = user_project.repository.tree(commit.id, path)
+        tree = user_project.repository.tree(commit.id, path, recursive: recursive)
 
         present tree.sorted_entries, with: Entities::RepoTreeObject
       end
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index c4dc2d9006af22f88e63cfabc80a0bd158a13220..38c8ad34f9d834f9da1ac79e6ad012b64d520a2d 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -18,6 +18,7 @@ describe API::API, api: true  do
 
       it "returns project commits" do
         get api("/projects/#{project.id}/repository/tree", user)
+
         expect(response).to have_http_status(200)
 
         expect(json_response).to be_an Array
@@ -43,6 +44,40 @@ describe API::API, api: true  do
     end
   end
 
+  
+  describe 'GET /projects/:id/repository/tree?recursive=1' do
+    context 'authorized user' do
+      before { project.team << [user2, :reporter] }
+
+      it 'should return recursive project paths tree' do
+        get api("/projects/#{project.id}/repository/tree?recursive=1", user)
+
+        expect(response.status).to eq(200)
+
+        expect(json_response).to be_an Array
+        expect(json_response[4]['name']).to eq('html')
+        expect(json_response[4]['path']).to eq('files/html')
+        expect(json_response[4]['type']).to eq('tree')
+        expect(json_response[4]['mode']).to eq('040000')
+      end
+
+      it 'returns a 404 for unknown ref' do
+        get api("/projects/#{project.id}/repository/tree?ref_name=foo&recursive=1", user)
+        expect(response).to have_http_status(404)
+
+        expect(json_response).to be_an Object
+        json_response['message'] == '404 Tree Not Found'
+      end      
+    end
+
+    context "unauthorized user" do
+      it "does not return project commits" do
+        get api("/projects/#{project.id}/repository/tree?recursive=1")
+        expect(response).to have_http_status(401)
+      end
+    end
+  end
+
   describe "GET /projects/:id/repository/blobs/:sha" do
     it "gets the raw file contents" do
       get api("/projects/#{project.id}/repository/blobs/master?filepath=README.md", user)