diff --git a/app/controllers/api/v1/instances/activity_controller.rb b/app/controllers/api/v1/instances/activity_controller.rb
index 4c17bd79c24b24de5e1faa71b4dd490b74edefad..06e4fd8b8f074f79e73890f0e9694eabcff9258c 100644
--- a/app/controllers/api/v1/instances/activity_controller.rb
+++ b/app/controllers/api/v1/instances/activity_controller.rb
@@ -3,6 +3,8 @@
 class Api::V1::Instances::ActivityController < Api::V1::Instances::BaseController
   before_action :require_enabled_api!
 
+  WEEKS_OF_ACTIVITY = 12
+
   def show
     cache_even_if_authenticated!
     render_with_cache json: :activity, expires_in: 1.day
@@ -11,23 +13,40 @@ class Api::V1::Instances::ActivityController < Api::V1::Instances::BaseControlle
   private
 
   def activity
-    statuses_tracker      = ActivityTracker.new('activity:statuses:local', :basic)
-    logins_tracker        = ActivityTracker.new('activity:logins', :unique)
-    registrations_tracker = ActivityTracker.new('activity:accounts:local', :basic)
-
-    (0...12).map do |i|
-      start_of_week = i.weeks.ago
-      end_of_week   = start_of_week + 6.days
-
-      {
-        week: start_of_week.to_i.to_s,
-        statuses: statuses_tracker.sum(start_of_week, end_of_week).to_s,
-        logins: logins_tracker.sum(start_of_week, end_of_week).to_s,
-        registrations: registrations_tracker.sum(start_of_week, end_of_week).to_s,
-      }
+    activity_weeks.map do |weeks_ago|
+      activity_json(*week_edge_days(weeks_ago))
     end
   end
 
+  def activity_json(start_of_week, end_of_week)
+    {
+      week: start_of_week.to_i.to_s,
+      statuses: statuses_tracker.sum(start_of_week, end_of_week).to_s,
+      logins: logins_tracker.sum(start_of_week, end_of_week).to_s,
+      registrations: registrations_tracker.sum(start_of_week, end_of_week).to_s,
+    }
+  end
+
+  def activity_weeks
+    0...WEEKS_OF_ACTIVITY
+  end
+
+  def week_edge_days(num)
+    [num.weeks.ago, num.weeks.ago + 6.days]
+  end
+
+  def statuses_tracker
+    ActivityTracker.new('activity:statuses:local', :basic)
+  end
+
+  def logins_tracker
+    ActivityTracker.new('activity:logins', :unique)
+  end
+
+  def registrations_tracker
+    ActivityTracker.new('activity:accounts:local', :basic)
+  end
+
   def require_enabled_api!
     head 404 unless Setting.activity_api_enabled && !limited_federation_mode?
   end
diff --git a/app/controllers/api/v1/instances/domain_blocks_controller.rb b/app/controllers/api/v1/instances/domain_blocks_controller.rb
index 8fb90305add242c17e5486a9fc549ee18109d3e7..7ec94312f45d20f4984193ddb9f22da0b761fc49 100644
--- a/app/controllers/api/v1/instances/domain_blocks_controller.rb
+++ b/app/controllers/api/v1/instances/domain_blocks_controller.rb
@@ -19,7 +19,19 @@ class Api::V1::Instances::DomainBlocksController < Api::V1::Instances::BaseContr
   private
 
   def require_enabled_api!
-    head 404 unless Setting.show_domain_blocks == 'all' || (Setting.show_domain_blocks == 'users' && user_signed_in?)
+    head 404 unless api_enabled?
+  end
+
+  def api_enabled?
+    show_domain_blocks_for_all? || show_domain_blocks_to_user?
+  end
+
+  def show_domain_blocks_for_all?
+    Setting.show_domain_blocks == 'all'
+  end
+
+  def show_domain_blocks_to_user?
+    Setting.show_domain_blocks == 'users' && user_signed_in?
   end
 
   def set_domain_blocks
diff --git a/spec/controllers/api/v1/instances/activity_controller_spec.rb b/spec/controllers/api/v1/instances/activity_controller_spec.rb
deleted file mode 100644
index b446a521f8bb9693bb0e51b3c465883fc44c11ee..0000000000000000000000000000000000000000
--- a/spec/controllers/api/v1/instances/activity_controller_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe Api::V1::Instances::ActivityController do
-  describe 'GET #show' do
-    it 'returns 200' do
-      get :show
-      expect(response).to have_http_status(200)
-    end
-
-    context 'with !Setting.activity_api_enabled' do
-      it 'returns 404' do
-        Setting.activity_api_enabled = false
-
-        get :show
-        expect(response).to have_http_status(404)
-      end
-    end
-  end
-end
diff --git a/spec/controllers/api/v1/instances/domain_blocks_controller_spec.rb b/spec/controllers/api/v1/instances/domain_blocks_controller_spec.rb
deleted file mode 100644
index 08f505c3d4e17187863fee022a8fd44a1885d0dc..0000000000000000000000000000000000000000
--- a/spec/controllers/api/v1/instances/domain_blocks_controller_spec.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-describe Api::V1::Instances::DomainBlocksController do
-  render_views
-
-  describe 'GET #index' do
-    it 'returns http success' do
-      Setting.show_domain_blocks = 'all'
-      get :index
-
-      expect(response).to have_http_status(200)
-    end
-  end
-end
diff --git a/spec/controllers/api/v1/instances/extended_descriptions_controller_spec.rb b/spec/controllers/api/v1/instances/extended_descriptions_controller_spec.rb
deleted file mode 100644
index 58c0d4b8f1cb53b2dad0a7fa216fb7324772cd63..0000000000000000000000000000000000000000
--- a/spec/controllers/api/v1/instances/extended_descriptions_controller_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-describe Api::V1::Instances::ExtendedDescriptionsController do
-  render_views
-
-  describe 'GET #show' do
-    it 'returns http success' do
-      get :show
-
-      expect(response).to have_http_status(200)
-    end
-  end
-end
diff --git a/spec/controllers/api/v1/instances/peers_controller_spec.rb b/spec/controllers/api/v1/instances/peers_controller_spec.rb
deleted file mode 100644
index 92b1019154f1e405b075b0023cb4aee89fba5a60..0000000000000000000000000000000000000000
--- a/spec/controllers/api/v1/instances/peers_controller_spec.rb
+++ /dev/null
@@ -1,21 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe Api::V1::Instances::PeersController do
-  describe 'GET #index' do
-    it 'returns 200' do
-      get :index
-      expect(response).to have_http_status(200)
-    end
-
-    context 'with !Setting.peers_api_enabled' do
-      it 'returns 404' do
-        Setting.peers_api_enabled = false
-
-        get :index
-        expect(response).to have_http_status(404)
-      end
-    end
-  end
-end
diff --git a/spec/controllers/api/v1/instances/privacy_policies_controller_spec.rb b/spec/controllers/api/v1/instances/privacy_policies_controller_spec.rb
deleted file mode 100644
index ac0bed9dc6eb6bc69f200b46962379525dca2c76..0000000000000000000000000000000000000000
--- a/spec/controllers/api/v1/instances/privacy_policies_controller_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-describe Api::V1::Instances::PrivacyPoliciesController do
-  render_views
-
-  describe 'GET #show' do
-    it 'returns http success' do
-      get :show
-
-      expect(response).to have_http_status(200)
-    end
-  end
-end
diff --git a/spec/controllers/api/v1/instances/rules_controller_spec.rb b/spec/controllers/api/v1/instances/rules_controller_spec.rb
deleted file mode 100644
index 5af50239b05804ee437e62323b6980451ed446d2..0000000000000000000000000000000000000000
--- a/spec/controllers/api/v1/instances/rules_controller_spec.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-describe Api::V1::Instances::RulesController do
-  render_views
-
-  describe 'GET #index' do
-    it 'returns http success' do
-      get :index
-
-      expect(response).to have_http_status(200)
-    end
-  end
-end
diff --git a/spec/controllers/api/v1/instances/translation_languages_controller_spec.rb b/spec/controllers/api/v1/instances/translation_languages_controller_spec.rb
deleted file mode 100644
index f79687df66b7adca9e0d6b26f2825fa3017a50cc..0000000000000000000000000000000000000000
--- a/spec/controllers/api/v1/instances/translation_languages_controller_spec.rb
+++ /dev/null
@@ -1,30 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-describe Api::V1::Instances::TranslationLanguagesController do
-  describe 'GET #show' do
-    context 'when no translation service is configured' do
-      it 'returns empty language matrix', :aggregate_failures do
-        get :show
-
-        expect(response).to have_http_status(200)
-        expect(body_as_json).to eq({})
-      end
-    end
-
-    context 'when a translation service is configured' do
-      before do
-        service = instance_double(TranslationService::DeepL, languages: { nil => %w(en de), 'en' => ['de'] })
-        allow(TranslationService).to receive_messages(configured?: true, configured: service)
-      end
-
-      it 'returns language matrix', :aggregate_failures do
-        get :show
-
-        expect(response).to have_http_status(200)
-        expect(body_as_json).to eq({ und: %w(en de), en: ['de'] })
-      end
-    end
-  end
-end
diff --git a/spec/controllers/api/v1/instances_controller_spec.rb b/spec/controllers/api/v1/instances_controller_spec.rb
deleted file mode 100644
index fcc2c9288ca9d7f007f669d0077e12a62b7b8224..0000000000000000000000000000000000000000
--- a/spec/controllers/api/v1/instances_controller_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe Api::V1::InstancesController do
-  render_views
-
-  let(:user)  { Fabricate(:user) }
-  let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) }
-
-  before do
-    allow(controller).to receive(:doorkeeper_token) { token }
-  end
-
-  describe 'GET #show' do
-    it 'returns http success' do
-      get :show
-
-      expect(response).to have_http_status(200)
-    end
-  end
-end
diff --git a/spec/controllers/api/v2/instances_controller_spec.rb b/spec/controllers/api/v2/instances_controller_spec.rb
deleted file mode 100644
index b7206da0a2ce67d9f1dafdc2e806322a60a527cf..0000000000000000000000000000000000000000
--- a/spec/controllers/api/v2/instances_controller_spec.rb
+++ /dev/null
@@ -1,22 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-describe Api::V2::InstancesController do
-  render_views
-
-  let(:user)  { Fabricate(:user) }
-  let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) }
-
-  before do
-    allow(controller).to receive(:doorkeeper_token) { token }
-  end
-
-  describe 'GET #show' do
-    it 'returns http success' do
-      get :show
-
-      expect(response).to have_http_status(200)
-    end
-  end
-end
diff --git a/spec/requests/api/v1/instance_spec.rb b/spec/requests/api/v1/instance_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..9cac280c4df0c3f311b0b19a6d6504978d4afc21
--- /dev/null
+++ b/spec/requests/api/v1/instance_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe 'Instances' do
+  let(:user)    { Fabricate(:user) }
+  let(:token)   { Fabricate(:accessible_access_token, resource_owner_id: user.id) }
+  let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
+
+  describe 'GET /api/v1/instance' do
+    context 'when not logged in' do
+      it 'returns http success and json' do
+        get api_v1_instance_path
+
+        expect(response)
+          .to have_http_status(200)
+
+        expect(body_as_json)
+          .to be_present
+          .and include(title: 'Mastodon')
+      end
+    end
+
+    context 'when logged in' do
+      it 'returns http success and json' do
+        get api_v1_instance_path, headers: headers
+
+        expect(response)
+          .to have_http_status(200)
+
+        expect(body_as_json)
+          .to be_present
+          .and include(title: 'Mastodon')
+      end
+    end
+  end
+end
diff --git a/spec/requests/api/v1/instances/activity_spec.rb b/spec/requests/api/v1/instances/activity_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d1f92ef36e5a0f0da30b746afae70ad26a8e4454
--- /dev/null
+++ b/spec/requests/api/v1/instances/activity_spec.rb
@@ -0,0 +1,40 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Activity' do
+  describe 'GET /api/v1/instance/activity' do
+    around do |example|
+      original = Setting.activity_api_enabled
+      example.run
+      Setting.activity_api_enabled = original
+    end
+
+    context 'with activity api enabled' do
+      before { Setting.activity_api_enabled = true }
+
+      it 'returns http success' do
+        get api_v1_instance_activity_path
+
+        expect(response)
+          .to have_http_status(200)
+
+        expect(body_as_json)
+          .to be_present
+          .and(be_an(Array))
+          .and(have_attributes(size: Api::V1::Instances::ActivityController::WEEKS_OF_ACTIVITY))
+      end
+    end
+
+    context 'with activity api diabled' do
+      before { Setting.activity_api_enabled = false }
+
+      it 'returns not found' do
+        get api_v1_instance_activity_path
+
+        expect(response)
+          .to have_http_status(404)
+      end
+    end
+  end
+end
diff --git a/spec/requests/api/v1/instances/domain_blocks_spec.rb b/spec/requests/api/v1/instances/domain_blocks_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..99b5e2b6aa468439d2bf7077aeeda9cf9001664e
--- /dev/null
+++ b/spec/requests/api/v1/instances/domain_blocks_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Domain Blocks' do
+  describe 'GET /api/v1/instance/domain_blocks' do
+    around do |example|
+      original = Setting.show_domain_blocks
+      example.run
+      Setting.show_domain_blocks = original
+    end
+
+    before do
+      Fabricate(:domain_block)
+    end
+
+    context 'with domain blocks set to all' do
+      before { Setting.show_domain_blocks = 'all' }
+
+      it 'returns http success' do
+        get api_v1_instance_domain_blocks_path
+
+        expect(response)
+          .to have_http_status(200)
+
+        expect(body_as_json)
+          .to be_present
+          .and(be_an(Array))
+          .and(have_attributes(size: 1))
+      end
+    end
+
+    context 'with domain blocks set to users' do
+      before { Setting.show_domain_blocks = 'users' }
+
+      it 'returns http not found' do
+        get api_v1_instance_domain_blocks_path
+
+        expect(response)
+          .to have_http_status(404)
+      end
+    end
+
+    context 'with domain blocks set to disabled' do
+      before { Setting.show_domain_blocks = 'disabled' }
+
+      it 'returns http not found' do
+        get api_v1_instance_domain_blocks_path
+
+        expect(response)
+          .to have_http_status(404)
+      end
+    end
+  end
+end
diff --git a/spec/requests/api/v1/instances/extended_descriptions_spec.rb b/spec/requests/api/v1/instances/extended_descriptions_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..64982de686396612ba0f526f2c0d545b613a4b61
--- /dev/null
+++ b/spec/requests/api/v1/instances/extended_descriptions_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Extended Descriptions' do
+  describe 'GET /api/v1/instance/extended_description' do
+    it 'returns http success' do
+      get api_v1_instance_extended_description_path
+
+      expect(response)
+        .to have_http_status(200)
+
+      expect(body_as_json)
+        .to be_present
+        .and include(:content)
+    end
+  end
+end
diff --git a/spec/requests/api/v1/instances/peers_spec.rb b/spec/requests/api/v1/instances/peers_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..d3400ae8fdd90a30a011d17feda5c6aedacd0a7b
--- /dev/null
+++ b/spec/requests/api/v1/instances/peers_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Peers' do
+  describe 'GET /api/v1/instance/peers' do
+    around do |example|
+      original = Setting.peers_api_enabled
+      example.run
+      Setting.peers_api_enabled = original
+    end
+
+    context 'with peers api enabled' do
+      before { Setting.peers_api_enabled = true }
+
+      it 'returns http success' do
+        get api_v1_instance_peers_path
+
+        expect(response)
+          .to have_http_status(200)
+
+        expect(body_as_json)
+          .to be_an(Array)
+      end
+    end
+
+    context 'with peers api diabled' do
+      before { Setting.peers_api_enabled = false }
+
+      it 'returns http not found' do
+        get api_v1_instance_peers_path
+
+        expect(response)
+          .to have_http_status(404)
+      end
+    end
+  end
+end
diff --git a/spec/requests/api/v1/instances/privacy_policies_spec.rb b/spec/requests/api/v1/instances/privacy_policies_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..24de98d880d5687cbabcc1890c0fbe9c644974ff
--- /dev/null
+++ b/spec/requests/api/v1/instances/privacy_policies_spec.rb
@@ -0,0 +1,18 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Privacy Policy' do
+  describe 'GET /api/v1/instance/privacy_policy' do
+    it 'returns http success' do
+      get api_v1_instance_privacy_policy_path
+
+      expect(response)
+        .to have_http_status(200)
+
+      expect(body_as_json)
+        .to be_present
+        .and include(:content)
+    end
+  end
+end
diff --git a/spec/requests/api/v1/instances/rules_spec.rb b/spec/requests/api/v1/instances/rules_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..65b8d78c7ddff9e643f4d5af73d8f36f40a40381
--- /dev/null
+++ b/spec/requests/api/v1/instances/rules_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Rules' do
+  describe 'GET /api/v1/instance/rules' do
+    it 'returns http success' do
+      get api_v1_instance_rules_path
+
+      expect(response)
+        .to have_http_status(200)
+
+      expect(body_as_json)
+        .to be_an(Array)
+    end
+  end
+end
diff --git a/spec/requests/api/v1/instances/translation_languages_spec.rb b/spec/requests/api/v1/instances/translation_languages_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..0b7dd8314d0e7bb0996ff98da5276cb63feeba68
--- /dev/null
+++ b/spec/requests/api/v1/instances/translation_languages_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe 'Translation Languages' do
+  describe 'GET /api/v1/instances/translation_languages' do
+    context 'when no translation service is configured' do
+      it 'returns empty language matrix', :aggregate_failures do
+        get api_v1_instance_translation_languages_path
+
+        expect(response)
+          .to have_http_status(200)
+
+        expect(body_as_json)
+          .to eq({})
+      end
+    end
+
+    context 'when a translation service is configured' do
+      before { configure_translation_service }
+
+      it 'returns language matrix', :aggregate_failures do
+        get api_v1_instance_translation_languages_path
+
+        expect(response)
+          .to have_http_status(200)
+
+        expect(body_as_json)
+          .to eq({ und: %w(en de), en: ['de'] })
+      end
+
+      private
+
+      def configure_translation_service
+        allow(TranslationService).to receive_messages(configured?: true, configured: service_double)
+      end
+
+      def service_double
+        instance_double(TranslationService::DeepL, languages: { nil => %w(en de), 'en' => ['de'] })
+      end
+    end
+  end
+end
diff --git a/spec/requests/api/v2/instance_spec.rb b/spec/requests/api/v2/instance_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..74574afbcf7eacc29d73f5a5e06c0caf62890290
--- /dev/null
+++ b/spec/requests/api/v2/instance_spec.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+describe 'Instances' do
+  let(:user)    { Fabricate(:user) }
+  let(:token)   { Fabricate(:accessible_access_token, resource_owner_id: user.id) }
+  let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
+
+  describe 'GET /api/v2/instance' do
+    context 'when logged out' do
+      it 'returns http success and json' do
+        get api_v2_instance_path
+
+        expect(response)
+          .to have_http_status(200)
+
+        expect(body_as_json)
+          .to be_present
+          .and include(title: 'Mastodon')
+      end
+    end
+
+    context 'when logged in' do
+      it 'returns http success and json' do
+        get api_v2_instance_path, headers: headers
+
+        expect(response)
+          .to have_http_status(200)
+
+        expect(body_as_json)
+          .to be_present
+          .and include(title: 'Mastodon')
+      end
+    end
+  end
+end