diff --git a/changelogs/unreleased/paginate-all-the-things.yml b/changelogs/unreleased/paginate-all-the-things.yml
new file mode 100644
index 0000000000000000000000000000000000000000..52f23ba52a987f4d2994c72b149f036607cff1c6
--- /dev/null
+++ b/changelogs/unreleased/paginate-all-the-things.yml
@@ -0,0 +1,4 @@
+---
+title: 'API: Paginate all endpoints that return an array'
+merge_request: 8606
+author: Robert Schilling
diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb
index 58a4df54bea7541498cc30d3b22cec618ec69cae..2ef327217ea7929796bc6e395aa0c29dfe859a6d 100644
--- a/lib/api/award_emoji.rb
+++ b/lib/api/award_emoji.rb
@@ -28,8 +28,8 @@ module API
           end
           get endpoint do
             if can_read_awardable?
-              awards = paginate(awardable.award_emoji)
-              present awards, with: Entities::AwardEmoji
+              awards = awardable.award_emoji
+              present paginate(awards), with: Entities::AwardEmoji
             else
               not_found!("Award Emoji")
             end
diff --git a/lib/api/boards.rb b/lib/api/boards.rb
index 13752eb49476c8ad6842a71d4fa936e3a72bff7e..f4226e5a89d759235177a299a195957072d73df0 100644
--- a/lib/api/boards.rb
+++ b/lib/api/boards.rb
@@ -1,6 +1,7 @@
 module API
-  # Boards API
   class Boards < Grape::API
+    include PaginationParams
+
     before { authenticate! }
 
     params do
@@ -11,9 +12,12 @@ module API
         detail 'This feature was introduced in 8.13'
         success Entities::Board
       end
+      params do
+        use :pagination
+      end
       get ':id/boards' do
         authorize!(:read_board, user_project)
-        present user_project.boards, with: Entities::Board
+        present paginate(user_project.boards), with: Entities::Board
       end
 
       params do
@@ -40,9 +44,12 @@ module API
           detail 'Does not include `done` list. This feature was introduced in 8.13'
           success Entities::List
         end
+        params do
+          use :pagination
+        end
         get '/lists' do
           authorize!(:read_board, user_project)
-          present board_lists, with: Entities::List
+          present paginate(board_lists), with: Entities::List
         end
 
         desc 'Get a list of a project board' do
diff --git a/lib/api/branches.rb b/lib/api/branches.rb
index 9331be1f7de1b46d545fab132ff78e397db12004..9d1f5a28ef62f76c84a77362320027949462de53 100644
--- a/lib/api/branches.rb
+++ b/lib/api/branches.rb
@@ -1,8 +1,9 @@
 require 'mime/types'
 
 module API
-  # Projects API
   class Branches < Grape::API
+    include PaginationParams
+
     before { authenticate! }
     before { authorize! :download_code, user_project }
 
@@ -13,10 +14,13 @@ module API
       desc 'Get a project repository branches' do
         success Entities::RepoBranch
       end
+      params do
+        use :pagination
+      end
       get ":id/repository/branches" do
-        branches = user_project.repository.branches.sort_by(&:name)
+        branches = ::Kaminari.paginate_array(user_project.repository.branches.sort_by(&:name))
 
-        present branches, with: Entities::RepoBranch, project: user_project
+        present paginate(branches), with: Entities::RepoBranch, project: user_project
       end
 
       desc 'Get a single branch' do
diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb
index 3f5183d46a2e39c8946e8de22a0f382b794058f6..982645c2f64fc3cc51d679f6f4a06088fd5f5cd5 100644
--- a/lib/api/deploy_keys.rb
+++ b/lib/api/deploy_keys.rb
@@ -1,12 +1,17 @@
 module API
   class DeployKeys < Grape::API
+    include PaginationParams
+
     before { authenticate! }
 
+    desc 'Return all deploy keys'
+    params do
+      use :pagination
+    end
     get "deploy_keys" do
       authenticated_as_admin!
 
-      keys = DeployKey.all
-      present keys, with: Entities::SSHKey
+      present paginate(DeployKey.all), with: Entities::SSHKey
     end
 
     params do
@@ -18,8 +23,11 @@ module API
       desc "Get a specific project's deploy keys" do
         success Entities::SSHKey
       end
+      params do
+        use :pagination
+      end
       get ":id/deploy_keys" do
-        present user_project.deploy_keys, with: Entities::SSHKey
+        present paginate(user_project.deploy_keys), with: Entities::SSHKey
       end
 
       desc 'Get single deploy key' do
diff --git a/lib/api/files.rb b/lib/api/files.rb
index 2ecdd747c8e598dbe9c6759e82e09cb3d8bbf787..6e16ccd2fd8c86b95f682f1c60ee2bc08c0d84df 100644
--- a/lib/api/files.rb
+++ b/lib/api/files.rb
@@ -1,5 +1,4 @@
 module API
-  # Projects API
   class Files < Grape::API
     helpers do
       def commit_params(attrs)
diff --git a/lib/api/helpers/pagination.rb b/lib/api/helpers/pagination.rb
index 2199eea7e5ffa40b78c86f8aeee35555de4c24b5..0764b58fb4cea5c53f85dc0db4d35854a6a6fe2c 100644
--- a/lib/api/helpers/pagination.rb
+++ b/lib/api/helpers/pagination.rb
@@ -2,7 +2,7 @@ module API
   module Helpers
     module Pagination
       def paginate(relation)
-        relation.page(params[:page]).per(params[:per_page].to_i).tap do |data|
+        relation.page(params[:page]).per(params[:per_page]).tap do |data|
           add_pagination_headers(data)
         end
       end
diff --git a/lib/api/labels.rb b/lib/api/labels.rb
index 652786d4e3eba436d881c3d1346138be8ef708ec..d2955af3f95e322beb588e5640d9190d2ceeb1ca 100644
--- a/lib/api/labels.rb
+++ b/lib/api/labels.rb
@@ -1,6 +1,7 @@
 module API
-  # Labels API
   class Labels < Grape::API
+    include PaginationParams
+    
     before { authenticate! }
 
     params do
@@ -10,8 +11,11 @@ module API
       desc 'Get all labels of the project' do
         success Entities::Label
       end
+      params do
+        use :pagination
+      end
       get ':id/labels' do
-        present available_labels, with: Entities::Label, current_user: current_user, project: user_project
+        present paginate(available_labels), with: Entities::Label, current_user: current_user, project: user_project
       end
 
       desc 'Create a new label' do
diff --git a/lib/api/merge_request_diffs.rb b/lib/api/merge_request_diffs.rb
index bc3d69f6904b6de2cbd08f20655f15c1cf2d40b7..4901a7cfea62d9bc5207b1a9908f4344f024fd46 100644
--- a/lib/api/merge_request_diffs.rb
+++ b/lib/api/merge_request_diffs.rb
@@ -1,6 +1,8 @@
 module API
   # MergeRequestDiff API
   class MergeRequestDiffs < Grape::API
+    include PaginationParams
+
     before { authenticate! }
 
     resource :projects do
@@ -12,12 +14,12 @@ module API
       params do
         requires :id, type: String, desc: 'The ID of a project'
         requires :merge_request_id, type: Integer, desc: 'The ID of a merge request'
+        use :pagination
       end
-
       get ":id/merge_requests/:merge_request_id/versions" do
         merge_request = find_merge_request_with_access(params[:merge_request_id])
 
-        present merge_request.merge_request_diffs, with: Entities::MergeRequestDiff
+        present paginate(merge_request.merge_request_diffs), with: Entities::MergeRequestDiff
       end
 
       desc 'Get a single merge request diff version' do
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index 8e09a6f73549418186c4e3b170dfba8427a286c7..bdd764abfebe50898dfd7fd73af02c6249a88ebc 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -119,8 +119,9 @@ module API
       end
       get ':id/merge_requests/:merge_request_id/commits' do
         merge_request = find_merge_request_with_access(params[:merge_request_id])
+        commits = ::Kaminari.paginate_array(merge_request.commits)
 
-        present merge_request.commits, with: Entities::RepoCommit
+        present paginate(commits), with: Entities::RepoCommit
       end
 
       desc 'Show the merge request changes' do
diff --git a/lib/api/pagination_params.rb b/lib/api/pagination_params.rb
index 8c1e4381a742402df0606202e0c9637a7b5e60d0..f566eb3ed2b12aaa88d31f859a3626f4cafcc454 100644
--- a/lib/api/pagination_params.rb
+++ b/lib/api/pagination_params.rb
@@ -15,8 +15,8 @@ module API
     included do
       helpers do
         params :pagination do
-          optional :page, type: Integer, desc: 'Current page number'
-          optional :per_page, type: Integer, desc: 'Number of items per page'
+          optional :page, type: Integer, default: 1, desc: 'Current page number'
+          optional :per_page, type: Integer, default: 20, desc: 'Number of items per page'
         end
       end
     end
diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb
index cb679e6658a3085a7e61f53fd8555a3f56ae3cc6..f7a28d7ad10284d3dc6fd85bc66ef2038a3f09f0 100644
--- a/lib/api/project_hooks.rb
+++ b/lib/api/project_hooks.rb
@@ -32,9 +32,7 @@ module API
         use :pagination
       end
       get ":id/hooks" do
-        hooks = paginate user_project.hooks
-
-        present hooks, with: Entities::ProjectHook
+        present paginate(user_project.hooks), with: Entities::ProjectHook
       end
 
       desc 'Get a project hook' do
diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb
index 4ca6646a6f1e99516bb8dab8e0ea5bd38e187203..bfda6f45b0a8d5697bab88b3d37d1a909aa901ce 100644
--- a/lib/api/repositories.rb
+++ b/lib/api/repositories.rb
@@ -2,6 +2,8 @@ require 'mime/types'
 
 module API
   class Repositories < Grape::API
+    include PaginationParams
+
     before { authorize! :download_code, user_project }
 
     params do
@@ -24,6 +26,7 @@ module API
         optional :ref_name, type: String, desc: 'The name of a repository branch or tag, if not given the default branch is used'
         optional :path, type: String, desc: 'The path of the tree'
         optional :recursive, type: Boolean, default: false, desc: 'Used to get a recursive tree'
+        use :pagination
       end
       get ':id/repository/tree' do
         ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
@@ -33,8 +36,8 @@ module API
         not_found!('Tree') unless commit
 
         tree = user_project.repository.tree(commit.id, path, recursive: params[:recursive])
-
-        present tree.sorted_entries, with: Entities::RepoTreeObject
+        entries = ::Kaminari.paginate_array(tree.sorted_entries)
+        present paginate(entries), with: Entities::RepoTreeObject
       end
 
       desc 'Get a raw file contents'
@@ -100,10 +103,13 @@ module API
       desc 'Get repository contributors' do
         success Entities::Contributor
       end
+      params do
+        use :pagination
+      end
       get ':id/repository/contributors' do
         begin
-          present user_project.repository.contributors,
-                  with: Entities::Contributor
+          contributors = ::Kaminari.paginate_array(user_project.repository.contributors)
+          present paginate(contributors), with: Entities::Contributor
         rescue
           not_found!
         end
diff --git a/lib/api/system_hooks.rb b/lib/api/system_hooks.rb
index 708ec8cfe70fccc626dfd1dd685049f74b61051e..d038a3fa828321257e31f7d654adeaf4a5cabc78 100644
--- a/lib/api/system_hooks.rb
+++ b/lib/api/system_hooks.rb
@@ -1,6 +1,7 @@
 module API
-  # Hooks API
   class SystemHooks < Grape::API
+    include PaginationParams
+
     before do
       authenticate!
       authenticated_as_admin!
@@ -10,10 +11,11 @@ module API
       desc 'Get the list of system hooks' do
         success Entities::Hook
       end
+      params do
+        use :pagination
+      end
       get do
-        hooks = SystemHook.all
-
-        present hooks, with: Entities::Hook
+        present paginate(SystemHook.all), with: Entities::Hook
       end
 
       desc 'Create a new system hook' do
diff --git a/lib/api/tags.rb b/lib/api/tags.rb
index b6fd8f569a91554c8c31ee6551fbefac136a5365..86759ab882f72f730333d0a7029d4fe5968c60c4 100644
--- a/lib/api/tags.rb
+++ b/lib/api/tags.rb
@@ -1,6 +1,7 @@
 module API
-  # Git Tags API
   class Tags < Grape::API
+    include PaginationParams
+
     before { authorize! :download_code, user_project }
 
     params do
@@ -10,9 +11,12 @@ module API
       desc 'Get a project repository tags' do
         success Entities::RepoTag
       end
+      params do
+        use :pagination
+      end
       get ":id/repository/tags" do
-        present user_project.repository.tags.sort_by(&:name).reverse,
-                with: Entities::RepoTag, project: user_project
+        tags = ::Kaminari.paginate_array(user_project.repository.tags.sort_by(&:name).reverse)
+        present paginate(tags), with: Entities::RepoTag, project: user_project
       end
 
       desc 'Get a single repository tag' do
diff --git a/lib/api/templates.rb b/lib/api/templates.rb
index 8a2d66efd892ade36ec127160bfe4417b96f66a5..2fcfe3d75c81a50d30179a27b9b8051b6c8e115a 100644
--- a/lib/api/templates.rb
+++ b/lib/api/templates.rb
@@ -1,5 +1,7 @@
 module API
   class Templates < Grape::API
+    include PaginationParams
+
     GLOBAL_TEMPLATE_TYPES = {
       gitignores: {
         klass: Gitlab::Template::GitignoreTemplate,
@@ -51,12 +53,14 @@ module API
     end
     params do
       optional :popular, type: Boolean, desc: 'If passed, returns only popular licenses'
+      use :pagination
     end
     get "templates/licenses" do
       options = {
         featured: declared(params).popular.present? ? true : nil
       }
-      present Licensee::License.all(options), with: ::API::Entities::RepoLicense
+      licences = ::Kaminari.paginate_array(Licensee::License.all(options))
+      present paginate(licences), with: Entities::RepoLicense
     end
 
     desc 'Get the text for a specific license' do
@@ -82,8 +86,12 @@ module API
         detail "This feature was introduced in GitLab #{gitlab_version}."
         success Entities::TemplatesList
       end
+      params do
+        use :pagination
+      end
       get "templates/#{template_type}" do
-        present klass.all, with: Entities::TemplatesList
+        templates = ::Kaminari.paginate_array(klass.all)
+        present paginate(templates), with: Entities::TemplatesLis
       end
 
       desc 'Get the text for a specific template present in local filesystem' do
diff --git a/lib/api/users.rb b/lib/api/users.rb
index 82ac3886ac3b9feb3e6b8034f4cc41d3fa432219..05538f5a42fbe8134e5538e5c42df3395d62afbe 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -209,6 +209,7 @@ module API
       end
       params do
         requires :id, type: Integer, desc: 'The ID of the user'
+        use :pagination
       end
       get ':id/keys' do
         authenticated_as_admin!
@@ -216,7 +217,7 @@ module API
         user = User.find_by(id: params[:id])
         not_found!('User') unless user
 
-        present user.keys, with: Entities::SSHKey
+        present paginate(user.keys), with: Entities::SSHKey
       end
 
       desc 'Delete an existing SSH key from a specified user. Available only for admins.' do
@@ -266,13 +267,14 @@ module API
       end
       params do
         requires :id, type: Integer, desc: 'The ID of the user'
+        use :pagination
       end
       get ':id/emails' do
         authenticated_as_admin!
         user = User.find_by(id: params[:id])
         not_found!('User') unless user
 
-        present user.emails, with: Entities::Email
+        present paginate(user.emails), with: Entities::Email
       end
 
       desc 'Delete an email address of a specified user. Available only for admins.' do
@@ -373,8 +375,11 @@ module API
       desc "Get the currently authenticated user's SSH keys" do
         success Entities::SSHKey
       end
+      params do
+        use :pagination
+      end
       get "keys" do
-        present current_user.keys, with: Entities::SSHKey
+        present paginate(current_user.keys), with: Entities::SSHKey
       end
 
       desc 'Get a single key owned by currently authenticated user' do
@@ -423,8 +428,11 @@ module API
       desc "Get the currently authenticated user's email addresses" do
         success Entities::Email
       end
+      params do
+        use :pagination
+      end
       get "emails" do
-        present current_user.emails, with: Entities::Email
+        present paginate(current_user.emails), with: Entities::Email
       end
 
       desc 'Get a single email address owned by the currently authenticated user' do
diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb
index 3e66236f6aef380fee172f00b5b017f76b75b5c6..91144b3e50dea19756b3166614d668a9ef5edc10 100644
--- a/spec/requests/api/branches_spec.rb
+++ b/spec/requests/api/branches_spec.rb
@@ -17,7 +17,7 @@ describe API::Branches, api: true  do
     it "returns an array of project branches" do
       project.repository.expire_all_method_caches
 
-      get api("/projects/#{project.id}/repository/branches", user)
+      get api("/projects/#{project.id}/repository/branches", user), per_page: 100
       expect(response).to have_http_status(200)
       expect(json_response).to be_an Array
       branch_names = json_response.map { |x| x['name'] }
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index ff10e79e4174fb286ad696041686330e0a0c1acc..7089009505ed2bb77c6c2bb5952e8540ca6600f8 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -191,6 +191,8 @@ describe API::MergeRequests, api: true  do
       commit = merge_request.commits.first
 
       expect(response.status).to eq 200
+      expect(response).to include_pagination_headers
+      expect(json_response).to be_an Array
       expect(json_response.size).to eq(merge_request.commits.size)
       expect(json_response.first['id']).to eq(commit.id)
       expect(json_response.first['title']).to eq(commit.title)
diff --git a/spec/requests/api/milestones_spec.rb b/spec/requests/api/milestones_spec.rb
index 8beef821d6c257aeeba8e17b34692dd53bc47778..4267a910b845c9c5bfa62c3418ce858dc7fa1d24 100644
--- a/spec/requests/api/milestones_spec.rb
+++ b/spec/requests/api/milestones_spec.rb
@@ -41,16 +41,6 @@ describe API::Milestones, api: true  do
       expect(json_response.length).to eq(1)
       expect(json_response.first['id']).to eq(closed_milestone.id)
     end
-  end
-
-  describe 'GET /projects/:id/milestones/:milestone_id' do
-    it 'returns a project milestone by id' do
-      get api("/projects/#{project.id}/milestones/#{milestone.id}", user)
-
-      expect(response).to have_http_status(200)
-      expect(json_response['title']).to eq(milestone.title)
-      expect(json_response['iid']).to eq(milestone.iid)
-    end
 
     it 'returns a project milestone by iid' do
       get api("/projects/#{project.id}/milestones?iid=#{closed_milestone.iid}", user)
@@ -69,6 +59,16 @@ describe API::Milestones, api: true  do
       expect(json_response.first['title']).to eq milestone.title
       expect(json_response.first['id']).to eq milestone.id
     end
+  end
+
+  describe 'GET /projects/:id/milestones/:milestone_id' do
+    it 'returns a project milestone by id' do
+      get api("/projects/#{project.id}/milestones/#{milestone.id}", user)
+
+      expect(response).to have_http_status(200)
+      expect(json_response['title']).to eq(milestone.title)
+      expect(json_response['iid']).to eq(milestone.iid)
+    end
 
     it 'returns 401 error if user not authenticated' do
       get api("/projects/#{project.id}/milestones/#{milestone.id}")
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 5958012672ed4db6a0951802bc45461fabfb5a78..56dc342f36daa1191f69f8c491a9f46d9438ccae 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -507,8 +507,11 @@ describe API::Users, api: true  do
       it 'returns array of ssh keys' do
         user.keys << key
         user.save
+
         get api("/users/#{user.id}/keys", admin)
+
         expect(response).to have_http_status(200)
+        expect(response).to include_pagination_headers
         expect(json_response).to be_an Array
         expect(json_response.first['title']).to eq(key.title)
       end
@@ -774,8 +777,11 @@ describe API::Users, api: true  do
       it "returns array of ssh keys" do
         user.keys << key
         user.save
+
         get api("/user/keys", user)
+
         expect(response).to have_http_status(200)
+        expect(response).to include_pagination_headers
         expect(json_response).to be_an Array
         expect(json_response.first["title"]).to eq(key.title)
       end