diff --git a/ee/lib/api/gitlab_subscriptions/subscriptions.rb b/ee/lib/api/gitlab_subscriptions/subscriptions.rb
index d83090a465be613d6a068da798a3095a82085d29..88409981706f64e75e22e34d9a4a15feef9fe6ae 100644
--- a/ee/lib/api/gitlab_subscriptions/subscriptions.rb
+++ b/ee/lib/api/gitlab_subscriptions/subscriptions.rb
@@ -18,7 +18,6 @@ class Subscriptions < ::API::Base
         end
         params do
           requires :start_date, type: Date, desc: 'The date when subscription was started'
-
           optional :end_date, type: Date, desc: 'End date of subscription'
           optional :plan_code, type: String, desc: 'Subscription tier code'
 
@@ -44,6 +43,39 @@ class Subscriptions < ::API::Base
             render_validation_error!(subscription)
           end
         end
+
+        desc 'Update the subscription for the namespace' do
+          success ::API::Entities::GitlabSubscription
+        end
+        params do
+          optional :start_date, type: Date, desc: 'Start date of subscription'
+          optional :end_date, type: Date, desc: 'End date of subscription'
+          optional :plan_code, type: String, desc: 'Subscription tier code'
+
+          optional :seats, type: Integer, desc: 'Number of seats in subscription'
+          optional :max_seats_used, type: Integer, desc: 'Highest number of active users in the last month'
+          optional :auto_renew, type: Grape::API::Boolean, desc: 'Whether subscription will auto renew on end date'
+
+          optional :trial, type: Grape::API::Boolean, desc: 'Whether the subscription is a trial'
+          optional :trial_ends_on, type: Date, desc: 'End date of trial'
+          optional :trial_starts_on, type: Date, desc: 'Start date of trial'
+          optional :trial_extension_type, type: Integer, desc: 'Whether the trial was extended or reactivated'
+        end
+        put ":id/gitlab_subscription" do
+          subscription = @namespace.gitlab_subscription
+
+          not_found!('GitlabSubscription') unless subscription
+
+          subscription_params = declared_params(include_missing: false)
+          subscription_params[:trial_starts_on] ||= subscription_params[:start_date] if subscription_params[:trial]
+          subscription_params[:updated_at] = Time.current
+
+          if subscription.update(subscription_params)
+            present subscription, with: ::API::Entities::GitlabSubscription
+          else
+            render_validation_error!(subscription)
+          end
+        end
       end
     end
   end
diff --git a/ee/lib/ee/api/namespaces.rb b/ee/lib/ee/api/namespaces.rb
index a95682b79b65a23cbe131546fa3da4d956a71bba..883031b05cba4321449ab7d871a49045c7eed72e 100644
--- a/ee/lib/ee/api/namespaces.rb
+++ b/ee/lib/ee/api/namespaces.rb
@@ -97,31 +97,6 @@ def update_namespace(namespace)
             present namespace.gitlab_subscription || {}, with: ::API::Entities::GitlabSubscription
           end
 
-          desc 'Update the subscription for the namespace' do
-            success ::API::Entities::GitlabSubscription
-          end
-          params do
-            use :gitlab_subscription_optional_attributes
-          end
-          put ":id/gitlab_subscription", urgency: :low, feature_category: :subscription_management do
-            authenticated_as_admin!
-
-            namespace = find_namespace!(params[:id])
-            subscription = namespace.gitlab_subscription
-
-            not_found!('GitlabSubscription') unless subscription
-
-            subscription_params = declared_params(include_missing: false)
-            subscription_params[:trial_starts_on] ||= subscription_params[:start_date] if subscription_params[:trial]
-            subscription_params[:updated_at] = Time.current
-
-            if subscription.update(subscription_params)
-              present subscription, with: ::API::Entities::GitlabSubscription
-            else
-              render_validation_error!(subscription)
-            end
-          end
-
           desc 'Creates a storage limit exclusion for a Namespace' do
             detail 'Creates a Namespaces::Storage::LimitExclusion'
             success code: 201, model: ::API::Entities::Namespaces::Storage::LimitExclusion
diff --git a/ee/spec/requests/api/gitlab_subscriptions/subscriptions_spec.rb b/ee/spec/requests/api/gitlab_subscriptions/subscriptions_spec.rb
index 7efe743935673df486ce36ae9ce6b6a620f198cc..92836c962a4dab1fb972b7a7871af09fff3f25af 100644
--- a/ee/spec/requests/api/gitlab_subscriptions/subscriptions_spec.rb
+++ b/ee/spec/requests/api/gitlab_subscriptions/subscriptions_spec.rb
@@ -3,8 +3,9 @@
 require 'spec_helper'
 
 RSpec.describe API::GitlabSubscriptions::Subscriptions, :aggregate_failures, feature_category: :plan_provisioning do
+  let_it_be(:admin) { create(:admin) }
+
   describe 'POST :id/gitlab_subscription', :saas do
-    let_it_be(:admin) { create(:admin) }
     let_it_be(:namespace) { create(:namespace) }
 
     it_behaves_like 'POST request permissions for admin mode' do
@@ -93,4 +94,148 @@
       end
     end
   end
+
+  describe 'PUT :id/gitlab_subscription', :saas do
+    let_it_be(:premium_plan) { create(:premium_plan) }
+    let_it_be(:namespace) { create(:group, name: 'test.test-group.22') }
+
+    let_it_be(:gitlab_subscription) do
+      create(:gitlab_subscription, namespace: namespace, start_date: '2018-01-01', end_date: '2019-01-01')
+    end
+
+    it_behaves_like 'PUT request permissions for admin mode' do
+      let(:path) { "/namespaces/#{namespace.id}/gitlab_subscription" }
+      let(:current_user) { admin }
+      let(:params) { { start_date: '2018-01-01', end_date: '2019-01-01', seats: 10, plan_code: 'ultimate' } }
+    end
+
+    context 'when authenticated as a regular user' do
+      it 'returns an unauthorized error' do
+        user = create(:user)
+
+        put api("/namespaces/#{namespace.id}/gitlab_subscription", user, admin_mode: false), params: { seats: 150 }
+
+        expect(response).to have_gitlab_http_status(:forbidden)
+      end
+    end
+
+    context 'when authenticated as an admin' do
+      context 'when namespace is not found' do
+        it 'returns a 404 error' do
+          put api("/namespaces/#{non_existing_record_id}/gitlab_subscription", admin, admin_mode: true),
+            params: { seats: 150 }
+
+          expect(response).to have_gitlab_http_status(:not_found)
+        end
+      end
+
+      context 'when namespace does not have a subscription' do
+        let_it_be(:namespace_2) { create(:group) }
+
+        it 'returns a 404 error' do
+          put api("/namespaces/#{namespace_2.id}/gitlab_subscription", admin, admin_mode: true), params: { seats: 150 }
+
+          expect(response).to have_gitlab_http_status(:not_found)
+        end
+      end
+
+      context 'when namespace is a project namespace' do
+        it 'returns a 404 error' do
+          project_namespace = create(:project, namespace: namespace)
+
+          put api("/namespaces/#{project_namespace.id}/gitlab_subscription", admin, admin_mode: true),
+            params: { seats: 150 }
+
+          expect(response).to have_gitlab_http_status(:not_found)
+          expect(json_response).to eq('message' => '404 Namespace Not Found')
+        end
+      end
+
+      context 'when params are invalid' do
+        it 'returns a 400 error' do
+          put api("/namespaces/#{namespace.id}/gitlab_subscription", admin, admin_mode: true), params: { seats: nil }
+
+          expect(response).to have_gitlab_http_status(:bad_request)
+        end
+      end
+
+      context 'when params are valid' do
+        it 'updates the subscription for the group' do
+          params = { seats: 150, plan_code: 'premium', start_date: '2018-01-01', end_date: '2019-01-01' }
+
+          put api("/namespaces/#{namespace.id}/gitlab_subscription", admin, admin_mode: true), params: params
+
+          expect(response).to have_gitlab_http_status(:ok)
+          expect(gitlab_subscription.reload.seats).to eq(150)
+          expect(gitlab_subscription.max_seats_used).to eq(0)
+          expect(gitlab_subscription.plan_name).to eq('premium')
+          expect(gitlab_subscription.plan_title).to eq('Premium')
+        end
+
+        it 'is successful when using full_path routing' do
+          params = { seats: 150, plan_code: 'premium', start_date: '2018-01-01', end_date: '2019-01-01' }
+
+          put api("/namespaces/#{namespace.full_path}/gitlab_subscription", admin, admin_mode: true), params: params
+
+          expect(response).to have_gitlab_http_status(:ok)
+        end
+
+        it 'does not clear out existing data because of defaults' do
+          gitlab_subscription.update!(seats: 20, max_seats_used: 42)
+
+          params = { plan_code: 'premium', start_date: '2018-01-01', end_date: '2019-01-01' }
+
+          put api("/namespaces/#{namespace.id}/gitlab_subscription", admin, admin_mode: true), params: params
+
+          expect(response).to have_gitlab_http_status(:ok)
+          expect(gitlab_subscription.reload).to have_attributes(
+            seats: 20,
+            max_seats_used: 42
+          )
+        end
+
+        it 'updates the timestamp when the attributes are the same' do
+          expect do
+            put api("/namespaces/#{namespace.full_path}/gitlab_subscription", admin, admin_mode: true),
+              params: namespace.gitlab_subscription.attributes
+          end.to change { gitlab_subscription.reload.updated_at }
+        end
+
+        context 'when starting a new term' do
+          it 'resets the seat attributes for the subscription' do
+            params = { seats: 150, plan_code: 'premium', start_date: '2018-01-01', end_date: '2019-01-01' }
+
+            gitlab_subscription.update!(seats: 20, max_seats_used: 42, seats_owed: 22)
+
+            new_start = gitlab_subscription.end_date + 1.year
+            new_end = new_start + 1.year
+            new_term_params = params.merge(start_date: new_start, end_date: new_end)
+
+            expect(gitlab_subscription.seats_in_use).to eq 0
+
+            put api("/namespaces/#{namespace.id}/gitlab_subscription", admin, admin_mode: true), params: new_term_params
+
+            expect(response).to have_gitlab_http_status(:ok)
+            expect(gitlab_subscription.reload).to have_attributes(
+              max_seats_used: 0,
+              seats_owed: 0
+            )
+          end
+        end
+
+        context 'when updating the trial expiration date' do
+          it 'updates the trial expiration date' do
+            date = 30.days.from_now.to_date
+
+            params = { seats: 150, plan_code: 'ultimate', trial_ends_on: date.iso8601 }
+
+            put api("/namespaces/#{namespace.id}/gitlab_subscription", admin, admin_mode: true), params: params
+
+            expect(response).to have_gitlab_http_status(:ok)
+            expect(gitlab_subscription.reload.trial_ends_on).to eq(date)
+          end
+        end
+      end
+    end
+  end
 end
diff --git a/ee/spec/requests/api/namespaces_spec.rb b/ee/spec/requests/api/namespaces_spec.rb
index 5501af8d37dd17811f5086e50b6029380c8eb968..65cd7e4652be008a6d819dee6920dc121c2f64fc 100644
--- a/ee/spec/requests/api/namespaces_spec.rb
+++ b/ee/spec/requests/api/namespaces_spec.rb
@@ -614,143 +614,6 @@ def do_get_subscription(current_user, namespace_id = namespace.id)
     end
   end
 
-  describe 'PUT :id/gitlab_subscription', :saas do
-    def do_put(namespace_id, current_user, payload, admin_mode: false)
-      put api("/namespaces/#{namespace_id}/gitlab_subscription", current_user, admin_mode: admin_mode), params: payload
-    end
-
-    let_it_be(:premium_plan) { create(:premium_plan) }
-    let_it_be(:namespace) { create(:group, name: 'test.test-group.22') }
-    let_it_be(:gitlab_subscription) { create(:gitlab_subscription, namespace: namespace, start_date: '2018/01/01', end_date: '2019/01/01') }
-
-    let(:params) do
-      {
-        seats: 150,
-        plan_code: 'premium',
-        start_date: '2018/01/01',
-        end_date: '2019/01/01'
-      }
-    end
-
-    it_behaves_like 'PUT request permissions for admin mode' do
-      let(:path) { "/namespaces/#{namespace.id}/gitlab_subscription" }
-    end
-
-    context 'when authenticated as a regular user' do
-      it 'returns an unauthorized error' do
-        do_put(namespace.id, user, { seats: 150 })
-
-        expect(response).to have_gitlab_http_status(:forbidden)
-      end
-    end
-
-    context 'when authenticated as an admin' do
-      context 'when namespace is not found' do
-        it 'returns a 404 error' do
-          do_put(non_existing_record_id, admin, params, admin_mode: true)
-
-          expect(response).to have_gitlab_http_status(:not_found)
-        end
-      end
-
-      context 'when namespace does not have a subscription' do
-        let_it_be(:namespace_2) { create(:group) }
-
-        it 'returns a 404 error' do
-          do_put(namespace_2.id, admin, params, admin_mode: true)
-
-          expect(response).to have_gitlab_http_status(:not_found)
-        end
-      end
-
-      context 'when namespace is a project namespace' do
-        it 'returns a 404 error' do
-          do_put(project_namespace.id, admin, params, admin_mode: true)
-
-          expect(response).to have_gitlab_http_status(:not_found)
-          expect(json_response).to eq('message' => '404 Namespace Not Found')
-        end
-      end
-
-      context 'when params are invalid' do
-        it 'returns a 400 error' do
-          do_put(namespace.id, admin, params.merge(seats: nil), admin_mode: true)
-
-          expect(response).to have_gitlab_http_status(:bad_request)
-        end
-      end
-
-      context 'when params are valid' do
-        it 'updates the subscription for the Group' do
-          do_put(namespace.id, admin, params, admin_mode: true)
-
-          expect(response).to have_gitlab_http_status(:ok)
-          expect(gitlab_subscription.reload.seats).to eq(150)
-          expect(gitlab_subscription.max_seats_used).to eq(0)
-          expect(gitlab_subscription.plan_name).to eq('premium')
-          expect(gitlab_subscription.plan_title).to eq('Premium')
-        end
-
-        it 'is successful using full_path when namespace path contains dots' do
-          do_put(namespace.id, admin, params, admin_mode: true)
-
-          expect(response).to have_gitlab_http_status(:ok)
-        end
-
-        it 'does not clear out existing data because of defaults' do
-          gitlab_subscription.update!(seats: 20, max_seats_used: 42)
-
-          do_put(namespace.id, admin, params.except(:seats), admin_mode: true)
-
-          expect(response).to have_gitlab_http_status(:ok)
-          expect(gitlab_subscription.reload).to have_attributes(
-            seats: 20,
-            max_seats_used: 42
-          )
-        end
-
-        it 'updates the timestamp when the attributes are the same' do
-          expect do
-            do_put(namespace.id, admin, gitlab_subscription.attributes, admin_mode: true)
-          end.to change { gitlab_subscription.reload.updated_at }
-        end
-
-        context 'when starting a new term' do
-          it 'resets the seat attributes for the subscription' do
-            gitlab_subscription.update!(seats: 20, max_seats_used: 42, seats_owed: 22)
-
-            new_start = gitlab_subscription.end_date + 1.year
-            new_end = new_start + 1.year
-            new_term_params = params.merge(start_date: new_start, end_date: new_end)
-
-            expect(gitlab_subscription.seats_in_use).to eq 0
-
-            do_put(namespace.id, admin, new_term_params, admin_mode: true)
-
-            expect(response).to have_gitlab_http_status(:ok)
-            expect(gitlab_subscription.reload).to have_attributes(
-              max_seats_used: 0,
-              seats_owed: 0
-            )
-          end
-        end
-      end
-    end
-
-    context 'setting the trial expiration date' do
-      context 'when the attr has a future date' do
-        it 'updates the trial expiration date' do
-          date = 30.days.from_now.to_date
-
-          do_put(namespace.id, admin, params.merge(trial_ends_on: date), admin_mode: true)
-
-          expect(response).to have_gitlab_http_status(:ok)
-          expect(gitlab_subscription.reload.trial_ends_on).to eq(date)
-        end
-      end
-    end
-  end
-
   describe 'POST :id/storage/limit_exclusion' do
     def do_post(namespace_id, current_user, payload, admin_mode: false)
       post api("/namespaces/#{namespace_id}/storage/limit_exclusion", current_user, admin_mode: admin_mode), params: payload