diff --git a/app/finders/packages/group_packages_finder.rb b/app/finders/packages/group_packages_finder.rb
index a51057571f1f937737a79587c94778a331142957..860c4068b31ae9bbd655d1d4b13aa54900130604 100644
--- a/app/finders/packages/group_packages_finder.rb
+++ b/app/finders/packages/group_packages_finder.rb
@@ -27,9 +27,9 @@ module Packages
         .including_tags
         .for_projects(group_projects_visible_to_current_user.select(:id))
         .processed
-        .has_version
         .sort_by_attribute("#{params[:order_by]}_#{params[:sort]}")
 
+      packages = filter_with_version(packages)
       packages = filter_by_package_type(packages)
       packages = filter_by_package_name(packages)
       packages
@@ -72,5 +72,11 @@ module Packages
 
       packages.search_by_name(params[:package_name])
     end
+
+    def filter_with_version(packages)
+      return packages if params[:include_versionless].present?
+
+      packages.has_version
+    end
   end
 end
diff --git a/app/finders/packages/packages_finder.rb b/app/finders/packages/packages_finder.rb
index 519e8bf9c34f2866208603d6dc908368f409d777..72a63224d2f6bf34b2cab929655089c378bf8ba7 100644
--- a/app/finders/packages/packages_finder.rb
+++ b/app/finders/packages/packages_finder.rb
@@ -18,7 +18,7 @@ module Packages
                         .including_project_route
                         .including_tags
                         .processed
-                        .has_version
+      packages = filter_with_version(packages)
       packages = filter_by_package_type(packages)
       packages = filter_by_package_name(packages)
       packages = order_packages(packages)
@@ -27,6 +27,12 @@ module Packages
 
     private
 
+    def filter_with_version(packages)
+      return packages if params[:include_versionless].present?
+
+      packages.has_version
+    end
+
     def filter_by_package_type(packages)
       return packages unless params[:package_type]
 
diff --git a/changelogs/unreleased/versionless-package-api-option.yml b/changelogs/unreleased/versionless-package-api-option.yml
new file mode 100644
index 0000000000000000000000000000000000000000..c929fe8c33797149e92be12ebe1c3a708e96e63e
--- /dev/null
+++ b/changelogs/unreleased/versionless-package-api-option.yml
@@ -0,0 +1,5 @@
+---
+title: Add include_versionless param to the Package API
+merge_request: 50669
+author:
+type: added
diff --git a/doc/api/packages.md b/doc/api/packages.md
index a52487e35a3cca7f12bda7723b0d8e8ffa0db133..2f588954ae11db28d77752f1f8ff7a8ec269c932 100644
--- a/doc/api/packages.md
+++ b/doc/api/packages.md
@@ -28,6 +28,7 @@ GET /projects/:id/packages
 | `sort`    | string | no | The direction of the order, either `asc` (default) for ascending order or `desc` for descending order. |
 | `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm`, `pypi`, `composer`, `nuget`, or `golang`. (_Introduced in GitLab 12.9_)
 | `package_name` | string | no | Filter the project packages with a fuzzy search by name. (_Introduced in GitLab 12.9_)
+| `include_versionless` | boolean | no | When set to true, versionless packages are included in the response. (_Introduced in GitLab 13.8_)
 
 ```shell
 curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/:id/packages"
@@ -88,6 +89,7 @@ GET /groups/:id/packages
 | `sort`    | string | no | The direction of the order, either `asc` (default) for ascending order or `desc` for descending order. |
 | `package_type` | string | no | Filter the returned packages by type. One of `conan`, `maven`, `npm`, `pypi`, `composer`, `nuget`, or `golang`. (_Introduced in GitLab 12.9_) |
 | `package_name` | string | no | Filter the project packages with a fuzzy search by name. (_[Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30980) in GitLab 13.0_)
+| `include_versionless` | boolean | no | When set to true, versionless packages are included in the response. (_Introduced in GitLab 13.8_)
 
 ```shell
 curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/packages?exclude_subgroups=true"
diff --git a/lib/api/group_packages.rb b/lib/api/group_packages.rb
index 31b28c3990f8c4f548878f4a4ee4b9bcb84a20e3..d482f4d05851fda229414f374bcbab2416c3c5be 100644
--- a/lib/api/group_packages.rb
+++ b/lib/api/group_packages.rb
@@ -31,12 +31,14 @@ module API
                                 desc: 'Return packages of a certain type'
         optional :package_name, type: String,
                                 desc: 'Return packages with this name'
+        optional :include_versionless, type: Boolean,
+                                       desc: 'Returns packages without a version'
       end
       get ':id/packages' do
         packages = Packages::GroupPackagesFinder.new(
           current_user,
           user_group,
-          declared(params).slice(:exclude_subgroups, :order_by, :sort, :package_type, :package_name)
+          declared(params).slice(:exclude_subgroups, :order_by, :sort, :package_type, :package_name, :include_versionless)
         ).execute
 
         present paginate(packages), with: ::API::Entities::Package, user: current_user, group: true
diff --git a/lib/api/project_packages.rb b/lib/api/project_packages.rb
index 56e94333433ee71bdd532f7f840a26330b37ff25..32636662987b7d927e9b76d3fb847f6ff47a2958 100644
--- a/lib/api/project_packages.rb
+++ b/lib/api/project_packages.rb
@@ -30,11 +30,13 @@ module API
                                 desc: 'Return packages of a certain type'
         optional :package_name, type: String,
                                 desc: 'Return packages with this name'
+        optional :include_versionless, type: Boolean,
+                       desc: 'Returns packages without a version'
       end
       get ':id/packages' do
         packages = ::Packages::PackagesFinder.new(
           user_project,
-          declared_params.slice(:order_by, :sort, :package_type, :package_name)
+          declared_params.slice(:order_by, :sort, :package_type, :package_name, :include_versionless)
         ).execute
 
         present paginate(packages), with: ::API::Entities::Package, user: current_user
diff --git a/spec/finders/packages/group_packages_finder_spec.rb b/spec/finders/packages/group_packages_finder_spec.rb
index 0db69de65a5c845f46d538cdcffef28e4c0dd331..8dd53b9c3f9813d5a7c9adc6caaa17452d927f2e 100644
--- a/spec/finders/packages/group_packages_finder_spec.rb
+++ b/spec/finders/packages/group_packages_finder_spec.rb
@@ -127,12 +127,6 @@ RSpec.describe Packages::GroupPackagesFinder do
         it { is_expected.to match_array([package1, package2]) }
       end
 
-      context 'does not include packages without version number' do
-        let_it_be(:package_without_version) { create(:maven_package, project: project, version: nil) }
-
-        it { is_expected.not_to include(package_without_version) }
-      end
-
       context 'with package_name' do
         let_it_be(:named_package) { create(:maven_package, project: project, name: 'maven') }
         let(:params) { { package_name: package_name } }
@@ -151,6 +145,8 @@ RSpec.describe Packages::GroupPackagesFinder do
           end
         end
       end
+
+      it_behaves_like 'concerning versionless param'
     end
 
     context 'group has package of all types' do
diff --git a/spec/finders/packages/packages_finder_spec.rb b/spec/finders/packages/packages_finder_spec.rb
index 925b003bb8eefdb12063821efee7d626d6cecc2e..77a171db144c5acd866fe743309a73d81480412d 100644
--- a/spec/finders/packages/packages_finder_spec.rb
+++ b/spec/finders/packages/packages_finder_spec.rb
@@ -81,10 +81,6 @@ RSpec.describe ::Packages::PackagesFinder do
       it { is_expected.to match_array([conan_package, maven_package]) }
     end
 
-    context 'does not include packages without version number' do
-      let_it_be(:package_without_version) { create(:maven_package, project: project, version: nil) }
-
-      it { is_expected.not_to include(package_without_version) }
-    end
+    it_behaves_like 'concerning versionless param'
   end
 end
diff --git a/spec/requests/api/group_packages_spec.rb b/spec/requests/api/group_packages_spec.rb
index 72ba25c59afed8b5eba1547f2c4e8b2f6cb43a38..26895e473ded2d8f7a9dc6e466c7a4d18840f30e 100644
--- a/spec/requests/api/group_packages_spec.rb
+++ b/spec/requests/api/group_packages_spec.rb
@@ -6,8 +6,9 @@ RSpec.describe API::GroupPackages do
   let_it_be(:group) { create(:group, :public) }
   let_it_be(:project) { create(:project, :public, namespace: group, name: 'project A') }
   let_it_be(:user) { create(:user) }
+  let(:params) { {} }
 
-  subject { get api(url) }
+  subject { get api(url), params: params }
 
   describe 'GET /groups/:id/packages' do
     let(:url) { "/groups/#{group.id}/packages" }
@@ -142,6 +143,7 @@ RSpec.describe API::GroupPackages do
       it_behaves_like 'returning response status', :bad_request
     end
 
+    it_behaves_like 'with versionless packages'
     it_behaves_like 'does not cause n^2 queries'
   end
 end
diff --git a/spec/requests/api/project_packages_spec.rb b/spec/requests/api/project_packages_spec.rb
index 4c8599d1a20d36fca3cf65ece1d643826f581fb3..eb86df36dbbc8288f1c46b395b9e2cbfee4f53d0 100644
--- a/spec/requests/api/project_packages_spec.rb
+++ b/spec/requests/api/project_packages_spec.rb
@@ -11,12 +11,13 @@ RSpec.describe API::ProjectPackages do
   let!(:another_package) { create(:npm_package) }
   let(:no_package_url) { "/projects/#{project.id}/packages/0" }
   let(:wrong_package_url) { "/projects/#{project.id}/packages/#{another_package.id}" }
+  let(:params) { {} }
 
   describe 'GET /projects/:id/packages' do
     let(:url) { "/projects/#{project.id}/packages" }
     let(:package_schema) { 'public_api/v4/packages/packages' }
 
-    subject { get api(url) }
+    subject { get api(url), params: params }
 
     context 'without the need for a license' do
       context 'project is public' do
@@ -118,6 +119,7 @@ RSpec.describe API::ProjectPackages do
         end
       end
 
+      it_behaves_like 'with versionless packages'
       it_behaves_like 'does not cause n^2 queries'
     end
   end
diff --git a/spec/support/shared_examples/finders/packages_shared_examples.rb b/spec/support/shared_examples/finders/packages_shared_examples.rb
new file mode 100644
index 0000000000000000000000000000000000000000..52976565b21cce638c8862608aa6dde060c6f0f9
--- /dev/null
+++ b/spec/support/shared_examples/finders/packages_shared_examples.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'concerning versionless param' do
+  let_it_be(:versionless_package) { create(:maven_package, project: project, version: nil) }
+
+  it { is_expected.not_to include(versionless_package) }
+
+  context 'with valid include_versionless param' do
+    let(:params) { { include_versionless: true } }
+
+    it { is_expected.to include(versionless_package) }
+  end
+
+  context 'with empty include_versionless param' do
+    let(:params) { { include_versionless: '' } }
+
+    it { is_expected.not_to include(versionless_package) }
+  end
+end
diff --git a/spec/support/shared_examples/services/packages_shared_examples.rb b/spec/support/shared_examples/services/packages_shared_examples.rb
index 70d29b4bc99d9d6fe81aa82d5e55bd71693aa275..fa307d2a9a62ffcac0e3364d11ad2566f611ca8f 100644
--- a/spec/support/shared_examples/services/packages_shared_examples.rb
+++ b/spec/support/shared_examples/services/packages_shared_examples.rb
@@ -220,3 +220,45 @@ RSpec.shared_examples 'package workhorse uploads' do
     end
   end
 end
+
+RSpec.shared_examples 'with versionless packages' do
+  context 'with versionless package' do
+    let!(:versionless_package) { create(:maven_package, project: project, version: nil) }
+
+    shared_examples 'not including the package' do
+      it 'does not return the package' do
+        subject
+
+        expect(json_response.map { |package| package['id'] }).not_to include(versionless_package.id)
+      end
+    end
+
+    it_behaves_like 'not including the package'
+
+    context 'with include_versionless param' do
+      context 'with true include_versionless param' do
+        [true, 'true', 1, '1'].each do |param|
+          context "for param #{param}" do
+            let(:params) { super().merge(include_versionless: param) }
+
+            it 'returns the package' do
+              subject
+
+              expect(json_response.map { |package| package['id'] }).to include(versionless_package.id)
+            end
+          end
+        end
+      end
+
+      context 'with falsy include_versionless param' do
+        [false, '', nil, 'false', 0, '0'].each do |param|
+          context "for param #{param}" do
+            let(:params) { super().merge(include_versionless: param) }
+
+            it_behaves_like 'not including the package'
+          end
+        end
+      end
+    end
+  end
+end