diff --git a/lib/api/helpers.rb b/lib/api/helpers.rb
index 253272539f7b66c2491d712c8b2f68353f32294e..bb94d5d14d07b844ad810727e9f918eff3c8bf7c 100644
--- a/lib/api/helpers.rb
+++ b/lib/api/helpers.rb
@@ -141,7 +141,7 @@ def find_user(id)
     def find_project(id)
       return unless id
 
-      projects = Project.without_deleted.not_hidden
+      projects = find_project_scopes
 
       if id.is_a?(Integer) || id =~ INTEGER_ID_REGEX
         projects.find_by(id: id)
@@ -151,6 +151,11 @@ def find_project(id)
     end
     # rubocop: enable CodeReuse/ActiveRecord
 
+    # Can be overriden by API endpoints
+    def find_project_scopes
+      Project.without_deleted.not_hidden
+    end
+
     def find_project!(id)
       project = find_project(id)
 
diff --git a/lib/api/project_repository_storage_moves.rb b/lib/api/project_repository_storage_moves.rb
index 5777b8754e7e04d6dedf33fecc033fb3a508bf91..b79348c87bfc7fd7ca36b336feb0628c89e82403 100644
--- a/lib/api/project_repository_storage_moves.rb
+++ b/lib/api/project_repository_storage_moves.rb
@@ -8,6 +8,16 @@ class ProjectRepositoryStorageMoves < ::API::Base
 
     feature_category :gitaly
 
+    helpers do
+      extend ::Gitlab::Utils::Override
+
+      # Allow to move projects in hidden/pending_delete state
+      override :find_project_scopes
+      def find_project_scopes
+        Project
+      end
+    end
+
     resource :project_repository_storage_moves do
       desc 'Get a list of all project repository storage moves' do
         detail 'This feature was introduced in GitLab 13.0.'
diff --git a/spec/requests/api/project_repository_storage_moves_spec.rb b/spec/requests/api/project_repository_storage_moves_spec.rb
index 96ed3042d00a060519469c05d5810bc27e0e2f37..7b5dc0d5ef820fbc5de9cd77ec4f26f0794d1910 100644
--- a/spec/requests/api/project_repository_storage_moves_spec.rb
+++ b/spec/requests/api/project_repository_storage_moves_spec.rb
@@ -8,5 +8,29 @@
     let_it_be(:storage_move) { create(:project_repository_storage_move, :scheduled, container: container) }
     let(:repository_storage_move_factory) { :project_repository_storage_move }
     let(:bulk_worker_klass) { Projects::ScheduleBulkRepositoryShardMovesWorker }
+
+    context 'when project is hidden' do
+      let_it_be(:container) { create(:project, :hidden) }
+      let_it_be(:storage_move) { create(:project_repository_storage_move, :scheduled, container: container) }
+
+      it_behaves_like 'get single container repository storage move' do
+        let(:container_id) { container.id }
+        let(:url) { "/projects/#{container_id}/repository_storage_moves/#{repository_storage_move_id}" }
+      end
+
+      it_behaves_like 'post single container repository storage move'
+    end
+
+    context 'when project is pending delete' do
+      let_it_be(:container) { create(:project, pending_delete: true) }
+      let_it_be(:storage_move) { create(:project_repository_storage_move, :scheduled, container: container) }
+
+      it_behaves_like 'get single container repository storage move' do
+        let(:container_id) { container.id }
+        let(:url) { "/projects/#{container_id}/repository_storage_moves/#{repository_storage_move_id}" }
+      end
+
+      it_behaves_like 'post single container repository storage move'
+    end
   end
 end
diff --git a/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb b/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb
index 3913d29e086de848852292ea46084dca09b7980a..181bab41e09289b83f0943ce36f42d57e891fe4a 100644
--- a/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/repository_storage_moves_shared_examples.rb
@@ -80,56 +80,9 @@ def get_container_repository_storage_moves
     end
   end
 
-  describe "GET /#{container_type}/:id/repository_storage_moves" do
-    let(:container_id) { container.id }
+  shared_examples 'post single container repository storage move' do
     let(:url) { "/#{container_type}/#{container_id}/repository_storage_moves" }
-
-    it_behaves_like 'get container repository storage move list'
-
-    context 'non-existent container' do
-      let(:container_id) { non_existing_record_id }
-
-      it 'returns not found' do
-        get api(url, user, admin_mode: user.admin?)
-
-        expect(response).to have_gitlab_http_status(:not_found)
-      end
-    end
-  end
-
-  describe "GET /#{container_type}/:id/repository_storage_moves/:repository_storage_move_id" do
     let(:container_id) { container.id }
-    let(:url) { "/#{container_type}/#{container_id}/repository_storage_moves/#{repository_storage_move_id}" }
-
-    it_behaves_like 'get single container repository storage move'
-
-    context 'non-existent container' do
-      let(:container_id) { non_existing_record_id }
-      let(:repository_storage_move_id) { storage_move.id }
-
-      it 'returns not found' do
-        get api(url, user, admin_mode: user.admin?)
-
-        expect(response).to have_gitlab_http_status(:not_found)
-      end
-    end
-  end
-
-  describe "GET /#{container_type.singularize}_repository_storage_moves" do
-    it_behaves_like 'get container repository storage move list' do
-      let(:url) { "/#{container_type.singularize}_repository_storage_moves" }
-    end
-  end
-
-  describe "GET /#{container_type.singularize}_repository_storage_moves/:repository_storage_move_id" do
-    it_behaves_like 'get single container repository storage move' do
-      let(:url) { "/#{container_type.singularize}_repository_storage_moves/#{repository_storage_move_id}" }
-    end
-  end
-
-  describe "POST /#{container_type}/:id/repository_storage_moves", :aggregate_failures do
-    let(:container_id) { container.id }
-    let(:url) { "/#{container_type}/#{container_id}/repository_storage_moves" }
     let(:destination_storage_name) { 'test_second_storage' }
 
     def create_container_repository_storage_move
@@ -186,6 +139,57 @@ def create_container_repository_storage_move
     end
   end
 
+  describe "GET /#{container_type}/:id/repository_storage_moves" do
+    let(:container_id) { container.id }
+    let(:url) { "/#{container_type}/#{container_id}/repository_storage_moves" }
+
+    it_behaves_like 'get container repository storage move list'
+
+    context 'non-existent container' do
+      let(:container_id) { non_existing_record_id }
+
+      it 'returns not found' do
+        get api(url, user, admin_mode: user.admin?)
+
+        expect(response).to have_gitlab_http_status(:not_found)
+      end
+    end
+  end
+
+  describe "GET /#{container_type}/:id/repository_storage_moves/:repository_storage_move_id" do
+    let(:container_id) { container.id }
+    let(:url) { "/#{container_type}/#{container_id}/repository_storage_moves/#{repository_storage_move_id}" }
+
+    it_behaves_like 'get single container repository storage move'
+
+    context 'non-existent container' do
+      let(:container_id) { non_existing_record_id }
+      let(:repository_storage_move_id) { storage_move.id }
+
+      it 'returns not found' do
+        get api(url, user, admin_mode: user.admin?)
+
+        expect(response).to have_gitlab_http_status(:not_found)
+      end
+    end
+  end
+
+  describe "GET /#{container_type.singularize}_repository_storage_moves" do
+    it_behaves_like 'get container repository storage move list' do
+      let(:url) { "/#{container_type.singularize}_repository_storage_moves" }
+    end
+  end
+
+  describe "GET /#{container_type.singularize}_repository_storage_moves/:repository_storage_move_id" do
+    it_behaves_like 'get single container repository storage move' do
+      let(:url) { "/#{container_type.singularize}_repository_storage_moves/#{repository_storage_move_id}" }
+    end
+  end
+
+  describe "POST /#{container_type}/:id/repository_storage_moves", :aggregate_failures do
+    it_behaves_like 'post single container repository storage move'
+  end
+
   describe "POST /#{container_type.singularize}_repository_storage_moves" do
     let(:url) { "/#{container_type.singularize}_repository_storage_moves" }
     let(:source_storage_name) { 'default' }