diff --git a/api_tests/package.json b/api_tests/package.json
index 84e5d3df579fd0fcaf52a6796a7a379fcd5f535b..8924847093c70ae51195124b7c7299aec4f37500 100644
--- a/api_tests/package.json
+++ b/api_tests/package.json
@@ -19,7 +19,7 @@
     "eslint": "^8.51.0",
     "eslint-plugin-prettier": "^5.0.1",
     "jest": "^29.5.0",
-    "lemmy-js-client": "0.19.0-rc.12",
+    "lemmy-js-client": "0.19.0-alpha.12",
     "prettier": "^3.0.0",
     "ts-jest": "^29.1.0",
     "typescript": "^5.0.4"
diff --git a/api_tests/src/community.spec.ts b/api_tests/src/community.spec.ts
index 2c97d629f52a20b3b2e78ec93a715fc8ed397227..a67cd693a0aa6ba582454d448cc3701c7bfa0953 100644
--- a/api_tests/src/community.spec.ts
+++ b/api_tests/src/community.spec.ts
@@ -25,7 +25,6 @@ import {
   getCommunityByName,
   blockInstance,
   waitUntil,
-  delay,
   alphaUrl,
   delta,
   betaAllowedInstances,
@@ -241,7 +240,7 @@ test("Admin actions in remote community are not federated to origin", async () =
     true,
     true,
   );
-  expect(banRes.banned).toBe(true);
+  expect(banRes.success).toBe(true);
 
   // ban doesnt federate to community's origin instance alpha
   let alphaPost = (await resolvePost(alpha, gammaPost.post)).post;
diff --git a/api_tests/src/post.spec.ts b/api_tests/src/post.spec.ts
index 8c1f2222628eebbeda6b36bd2eab4e218649d6c7..f9af236ce8a6cd83b27223d6faf2508789b578fd 100644
--- a/api_tests/src/post.spec.ts
+++ b/api_tests/src/post.spec.ts
@@ -415,7 +415,7 @@ test("Enforce site ban for federated user", async () => {
     true,
     true,
   );
-  expect(banAlpha.banned).toBe(true);
+  expect(banAlpha.success).toBe(true);
 
   // alpha ban should be federated to beta
   let alphaUserOnBeta1 = await waitUntil(
@@ -437,7 +437,7 @@ test("Enforce site ban for federated user", async () => {
     false,
     false,
   );
-  expect(unBanAlpha.banned).toBe(false);
+  expect(unBanAlpha.success).toBe(true);
 
   // Login gets invalidated by ban, need to login again
   if (!alphaUserPerson) {
@@ -479,7 +479,7 @@ test.skip("Enforce community ban for federated user", async () => {
     true,
     true,
   );
-  expect(banAlpha.banned).toBe(true);
+  expect(banAlpha.success).toBe(true);
 
   // ensure that the post by alpha got removed
   await expect(getPost(alpha, searchBeta1.posts[0].post.id)).rejects.toBe(
@@ -499,7 +499,7 @@ test.skip("Enforce community ban for federated user", async () => {
     false,
     false,
   );
-  expect(unBanAlpha.banned).toBe(false);
+  expect(unBanAlpha.success).toBe(true);
   let postRes3 = await createPost(alpha, betaCommunity.community.id);
   expect(postRes3.post_view.post).toBeDefined();
   expect(postRes3.post_view.community.local).toBe(false);
diff --git a/api_tests/src/shared.ts b/api_tests/src/shared.ts
index e4dabb1d402062c62d5b8a9f0143564d755ba430..fce25adc2dc7aa12a65f11b23d14bbdd521a4c2c 100644
--- a/api_tests/src/shared.ts
+++ b/api_tests/src/shared.ts
@@ -1,12 +1,12 @@
 import {
   BlockInstance,
-  BlockInstanceResponse,
   GetReplies,
   GetRepliesResponse,
   GetUnreadCountResponse,
   InstanceId,
   LemmyHttp,
   PostView,
+  SuccessResponse,
 } from "lemmy-js-client";
 import { CreatePost } from "lemmy-js-client/dist/types/CreatePost";
 import { DeletePost } from "lemmy-js-client/dist/types/DeletePost";
@@ -27,9 +27,7 @@ import { ResolveObjectResponse } from "lemmy-js-client/dist/types/ResolveObjectR
 import { Search } from "lemmy-js-client/dist/types/Search";
 import { SearchResponse } from "lemmy-js-client/dist/types/SearchResponse";
 import { Comment } from "lemmy-js-client/dist/types/Comment";
-import { BanPersonResponse } from "lemmy-js-client/dist/types/BanPersonResponse";
 import { BanPerson } from "lemmy-js-client/dist/types/BanPerson";
-import { BanFromCommunityResponse } from "lemmy-js-client/dist/types/BanFromCommunityResponse";
 import { BanFromCommunity } from "lemmy-js-client/dist/types/BanFromCommunity";
 import { CommunityResponse } from "lemmy-js-client/dist/types/CommunityResponse";
 import { FollowCommunity } from "lemmy-js-client/dist/types/FollowCommunity";
@@ -55,7 +53,6 @@ import { Register } from "lemmy-js-client/dist/types/Register";
 import { SaveUserSettings } from "lemmy-js-client/dist/types/SaveUserSettings";
 import { DeleteAccount } from "lemmy-js-client/dist/types/DeleteAccount";
 import { GetSiteResponse } from "lemmy-js-client/dist/types/GetSiteResponse";
-import { DeleteAccountResponse } from "lemmy-js-client/dist/types/DeleteAccountResponse";
 import { PrivateMessagesResponse } from "lemmy-js-client/dist/types/PrivateMessagesResponse";
 import { GetPrivateMessages } from "lemmy-js-client/dist/types/GetPrivateMessages";
 import { PostReportResponse } from "lemmy-js-client/dist/types/PostReportResponse";
@@ -385,7 +382,7 @@ export async function banPersonFromSite(
   person_id: number,
   ban: boolean,
   remove_data: boolean,
-): Promise<BanPersonResponse> {
+): Promise<SuccessResponse> {
   // Make sure lemmy-beta/c/main is cached on lemmy_alpha
   let form: BanPerson = {
     person_id,
@@ -401,7 +398,7 @@ export async function banPersonFromCommunity(
   community_id: number,
   remove_data: boolean,
   ban: boolean,
-): Promise<BanFromCommunityResponse> {
+): Promise<SuccessResponse> {
   let form: BanFromCommunity = {
     person_id,
     community_id,
@@ -689,9 +686,7 @@ export async function getPersonDetails(
   return api.getPersonDetails(form);
 }
 
-export async function deleteUser(
-  api: LemmyHttp,
-): Promise<DeleteAccountResponse> {
+export async function deleteUser(api: LemmyHttp): Promise<SuccessResponse> {
   let form: DeleteAccount = {
     delete_content: true,
     password,
@@ -788,7 +783,7 @@ export function blockInstance(
   api: LemmyHttp,
   instance_id: InstanceId,
   block: boolean,
-): Promise<BlockInstanceResponse> {
+): Promise<SuccessResponse> {
   let form: BlockInstance = {
     instance_id,
     block,
diff --git a/api_tests/yarn.lock b/api_tests/yarn.lock
index 56764e09697b4833afe00087fb0f1a94249cd2a1..f528a91448033341d4bbfeeb796b31b2faeb3520 100644
--- a/api_tests/yarn.lock
+++ b/api_tests/yarn.lock
@@ -2275,10 +2275,10 @@ kleur@^3.0.3:
   resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e"
   integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==
 
-lemmy-js-client@0.19.0-rc.12:
-  version "0.19.0-rc.12"
-  resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.19.0-rc.12.tgz#e3bd4e21b1966d583ab790ef70ece8394b012b48"
-  integrity sha512-1iu2fW9vlb3TrI+QR/ODP3+5pWZB0rUqL1wH09IzomDXohCqoQvfmXpwArmgF4Eq8GZgjkcfeMDC2gMrfw/i7Q==
+lemmy-js-client@0.19.0-alpha.12:
+  version "0.19.0-alpha.12"
+  resolved "https://registry.yarnpkg.com/lemmy-js-client/-/lemmy-js-client-0.19.0-alpha.12.tgz#0f98743483b3859414e7accce905105a7fc6df78"
+  integrity sha512-4SicZRNxZpLAxrjP54eRJmFHJ2AjNbWJv3PuTp2g6tkLQPUukDr8RsEOoDXDoIoqadgR3B5z1ujnuTtQrVrFKg==
   dependencies:
     cross-fetch "^3.1.5"
     form-data "^4.0.0"
diff --git a/crates/api/src/community/add_mod.rs b/crates/api/src/community/add_mod.rs
index 9d055c65492ee3d1f52788c069c172b7f3c3a60f..e8bf2c19fc7c4bc4c0652fa2bb2976aade8ba269 100644
--- a/crates/api/src/community/add_mod.rs
+++ b/crates/api/src/community/add_mod.rs
@@ -1,10 +1,11 @@
 use activitypub_federation::config::Data;
 use actix_web::web::Json;
 use lemmy_api_common::{
-  community::{AddModToCommunity, AddModToCommunityResponse},
+  community::AddModToCommunity,
   context::LemmyContext,
   send_activity::{ActivityChannel, SendActivityData},
   utils::check_community_mod_action,
+  SuccessResponse,
 };
 use lemmy_db_schema::{
   source::{
@@ -14,7 +15,6 @@ use lemmy_db_schema::{
   traits::{Crud, Joinable},
 };
 use lemmy_db_views::structs::LocalUserView;
-use lemmy_db_views_actor::structs::CommunityModeratorView;
 use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
 
 #[tracing::instrument(skip(context))]
@@ -22,7 +22,7 @@ pub async fn add_mod_to_community(
   data: Json<AddModToCommunity>,
   context: Data<LemmyContext>,
   local_user_view: LocalUserView,
-) -> Result<Json<AddModToCommunityResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   let community_id = data.community_id;
 
   // Verify that only mods or admins can add mod
@@ -63,11 +63,6 @@ pub async fn add_mod_to_community(
 
   ModAddCommunity::create(&mut context.pool(), &form).await?;
 
-  // Note: in case a remote mod is added, this returns the old moderators list, it will only get
-  //       updated once we receive an activity from the community (like `Announce/Add/Moderator`)
-  let community_id = data.community_id;
-  let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
-
   ActivityChannel::submit_activity(
     SendActivityData::AddModToCommunity(
       local_user_view.person,
@@ -79,5 +74,5 @@ pub async fn add_mod_to_community(
   )
   .await?;
 
-  Ok(Json(AddModToCommunityResponse { moderators }))
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/crates/api/src/community/ban.rs b/crates/api/src/community/ban.rs
index f662c4a08911b6f9ee9213bd6e3ac3a9e23f9bc1..8e315568de9d044cfa5be0a2645701986181e65e 100644
--- a/crates/api/src/community/ban.rs
+++ b/crates/api/src/community/ban.rs
@@ -1,10 +1,11 @@
 use activitypub_federation::config::Data;
 use actix_web::web::Json;
 use lemmy_api_common::{
-  community::{BanFromCommunity, BanFromCommunityResponse},
+  community::BanFromCommunity,
   context::LemmyContext,
   send_activity::{ActivityChannel, SendActivityData},
   utils::{check_community_mod_action, check_expire_time, remove_user_data_in_community},
+  SuccessResponse,
 };
 use lemmy_db_schema::{
   source::{
@@ -30,7 +31,7 @@ pub async fn ban_from_community(
   data: Json<BanFromCommunity>,
   context: Data<LemmyContext>,
   local_user_view: LocalUserView,
-) -> Result<Json<BanFromCommunityResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   let banned_person_id = data.person_id;
   let remove_data = data.remove_data.unwrap_or(false);
   let expires = check_expire_time(data.expires)?;
@@ -102,8 +103,5 @@ pub async fn ban_from_community(
   )
   .await?;
 
-  Ok(Json(BanFromCommunityResponse {
-    person_view,
-    banned: data.ban,
-  }))
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/crates/api/src/community/block.rs b/crates/api/src/community/block.rs
index fd4a5a01bf3b268252871203f1a2b1a738331c22..3c4e7ed9c729479701777b3a23740f7122ddea95 100644
--- a/crates/api/src/community/block.rs
+++ b/crates/api/src/community/block.rs
@@ -1,9 +1,10 @@
 use activitypub_federation::config::Data;
 use actix_web::web::Json;
 use lemmy_api_common::{
-  community::{BlockCommunity, BlockCommunityResponse},
+  community::BlockCommunity,
   context::LemmyContext,
   send_activity::{ActivityChannel, SendActivityData},
+  SuccessResponse,
 };
 use lemmy_db_schema::{
   source::{
@@ -21,7 +22,7 @@ pub async fn block_community(
   data: Json<BlockCommunity>,
   context: Data<LemmyContext>,
   local_user_view: LocalUserView,
-) -> Result<Json<BlockCommunityResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   let community_id = data.community_id;
   let person_id = local_user_view.person.id;
   let community_block_form = CommunityBlockForm {
@@ -63,8 +64,5 @@ pub async fn block_community(
   )
   .await?;
 
-  Ok(Json(BlockCommunityResponse {
-    blocked: data.block,
-    community_view,
-  }))
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/crates/api/src/local_user/add_admin.rs b/crates/api/src/local_user/add_admin.rs
index 50233587606d26a468ff5a15d459305d2e7c8f8a..0fc9989b91b8afa306c01b393eedf2245617381d 100644
--- a/crates/api/src/local_user/add_admin.rs
+++ b/crates/api/src/local_user/add_admin.rs
@@ -1,9 +1,5 @@
 use actix_web::web::{Data, Json};
-use lemmy_api_common::{
-  context::LemmyContext,
-  person::{AddAdmin, AddAdminResponse},
-  utils::is_admin,
-};
+use lemmy_api_common::{context::LemmyContext, person::AddAdmin, utils::is_admin, SuccessResponse};
 use lemmy_db_schema::{
   source::{
     local_user::{LocalUser, LocalUserUpdateForm},
@@ -12,7 +8,6 @@ use lemmy_db_schema::{
   traits::Crud,
 };
 use lemmy_db_views::structs::LocalUserView;
-use lemmy_db_views_actor::structs::PersonView;
 use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
 
 #[tracing::instrument(skip(context))]
@@ -20,7 +15,7 @@ pub async fn add_admin(
   data: Json<AddAdmin>,
   context: Data<LemmyContext>,
   local_user_view: LocalUserView,
-) -> Result<Json<AddAdminResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   // Make sure user is an admin
   is_admin(&local_user_view)?;
 
@@ -49,7 +44,5 @@ pub async fn add_admin(
 
   ModAdd::create(&mut context.pool(), &form).await?;
 
-  let admins = PersonView::admins(&mut context.pool()).await?;
-
-  Ok(Json(AddAdminResponse { admins }))
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/crates/api/src/local_user/ban_person.rs b/crates/api/src/local_user/ban_person.rs
index d7c47e6192e18dda833c2e9532686303a0a826cb..caa30465dbb931157e07ef16407e99812c8237e6 100644
--- a/crates/api/src/local_user/ban_person.rs
+++ b/crates/api/src/local_user/ban_person.rs
@@ -2,9 +2,10 @@ use activitypub_federation::config::Data;
 use actix_web::web::Json;
 use lemmy_api_common::{
   context::LemmyContext,
-  person::{BanPerson, BanPersonResponse},
+  person::BanPerson,
   send_activity::{ActivityChannel, SendActivityData},
   utils::{check_expire_time, is_admin, remove_user_data},
+  SuccessResponse,
 };
 use lemmy_db_schema::{
   source::{
@@ -26,7 +27,7 @@ pub async fn ban_from_site(
   data: Json<BanPerson>,
   context: Data<LemmyContext>,
   local_user_view: LocalUserView,
-) -> Result<Json<BanPersonResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   // Make sure user is an admin
   is_admin(&local_user_view)?;
 
@@ -81,8 +82,5 @@ pub async fn ban_from_site(
   )
   .await?;
 
-  Ok(Json(BanPersonResponse {
-    person_view,
-    banned: data.ban,
-  }))
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/crates/api/src/local_user/block.rs b/crates/api/src/local_user/block.rs
index cb345616bb59b2c15af0ccb4705b1cbf6c9f5d65..2524c0d8eb3f82174acbe462c7027151f0af7f9d 100644
--- a/crates/api/src/local_user/block.rs
+++ b/crates/api/src/local_user/block.rs
@@ -1,14 +1,10 @@
 use actix_web::web::{Data, Json};
-use lemmy_api_common::{
-  context::LemmyContext,
-  person::{BlockPerson, BlockPersonResponse},
-};
+use lemmy_api_common::{context::LemmyContext, person::BlockPerson, SuccessResponse};
 use lemmy_db_schema::{
   source::person_block::{PersonBlock, PersonBlockForm},
   traits::Blockable,
 };
 use lemmy_db_views::structs::LocalUserView;
-use lemmy_db_views_actor::structs::PersonView;
 use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
 
 #[tracing::instrument(skip(context))]
@@ -16,7 +12,7 @@ pub async fn block_person(
   data: Json<BlockPerson>,
   context: Data<LemmyContext>,
   local_user_view: LocalUserView,
-) -> Result<Json<BlockPersonResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   let target_id = data.person_id;
   let person_id = local_user_view.person.id;
 
@@ -45,9 +41,5 @@ pub async fn block_person(
       .with_lemmy_type(LemmyErrorType::PersonBlockAlreadyExists)?;
   }
 
-  let person_view = PersonView::read(&mut context.pool(), target_id).await?;
-  Ok(Json(BlockPersonResponse {
-    person_view,
-    blocked: data.block,
-  }))
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/crates/api/src/local_user/notifications/mark_reply_read.rs b/crates/api/src/local_user/notifications/mark_reply_read.rs
index f7b259c94b1a914b9dc7c31e0e6bb2aed38f3abd..cc8a9774ee15d856fa7a8779ba5e3aa620f26575 100644
--- a/crates/api/src/local_user/notifications/mark_reply_read.rs
+++ b/crates/api/src/local_user/notifications/mark_reply_read.rs
@@ -1,14 +1,10 @@
 use actix_web::web::{Data, Json};
-use lemmy_api_common::{
-  context::LemmyContext,
-  person::{CommentReplyResponse, MarkCommentReplyAsRead},
-};
+use lemmy_api_common::{context::LemmyContext, person::MarkCommentReplyAsRead, SuccessResponse};
 use lemmy_db_schema::{
   source::comment_reply::{CommentReply, CommentReplyUpdateForm},
   traits::Crud,
 };
 use lemmy_db_views::structs::LocalUserView;
-use lemmy_db_views_actor::structs::CommentReplyView;
 use lemmy_utils::error::{LemmyError, LemmyErrorExt, LemmyErrorType};
 
 #[tracing::instrument(skip(context))]
@@ -16,7 +12,7 @@ pub async fn mark_reply_as_read(
   data: Json<MarkCommentReplyAsRead>,
   context: Data<LemmyContext>,
   local_user_view: LocalUserView,
-) -> Result<Json<CommentReplyResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   let comment_reply_id = data.comment_reply_id;
   let read_comment_reply = CommentReply::read(&mut context.pool(), comment_reply_id).await?;
 
@@ -35,10 +31,5 @@ pub async fn mark_reply_as_read(
   .await
   .with_lemmy_type(LemmyErrorType::CouldntUpdateComment)?;
 
-  let comment_reply_id = read_comment_reply.id;
-  let person_id = local_user_view.person.id;
-  let comment_reply_view =
-    CommentReplyView::read(&mut context.pool(), comment_reply_id, Some(person_id)).await?;
-
-  Ok(Json(CommentReplyResponse { comment_reply_view }))
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/crates/api/src/site/block.rs b/crates/api/src/site/block.rs
index be48e8ce85c57419209d7078b3bb4708d79251f7..6cf220038b78987fc9b4f3b4c160353495b804b1 100644
--- a/crates/api/src/site/block.rs
+++ b/crates/api/src/site/block.rs
@@ -1,9 +1,6 @@
 use activitypub_federation::config::Data;
 use actix_web::web::Json;
-use lemmy_api_common::{
-  context::LemmyContext,
-  site::{BlockInstance, BlockInstanceResponse},
-};
+use lemmy_api_common::{context::LemmyContext, site::BlockInstance, SuccessResponse};
 use lemmy_db_schema::{
   source::instance_block::{InstanceBlock, InstanceBlockForm},
   traits::Blockable,
@@ -16,7 +13,7 @@ pub async fn block_instance(
   data: Json<BlockInstance>,
   local_user_view: LocalUserView,
   context: Data<LemmyContext>,
-) -> Result<Json<BlockInstanceResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   let instance_id = data.instance_id;
   let person_id = local_user_view.person.id;
   let instance_block_form = InstanceBlockForm {
@@ -34,7 +31,5 @@ pub async fn block_instance(
       .with_lemmy_type(LemmyErrorType::InstanceBlockAlreadyExists)?;
   }
 
-  Ok(Json(BlockInstanceResponse {
-    blocked: data.block,
-  }))
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/crates/api/src/site/purge/comment.rs b/crates/api/src/site/purge/comment.rs
index 1537bc4166936ccf7f302d49174700766fa98713..aa55dd3c9d8a9e320e6918a6b2d612fba0e5179e 100644
--- a/crates/api/src/site/purge/comment.rs
+++ b/crates/api/src/site/purge/comment.rs
@@ -1,8 +1,9 @@
 use actix_web::web::{Data, Json};
 use lemmy_api_common::{
   context::LemmyContext,
-  site::{PurgeComment, PurgeItemResponse},
+  site::PurgeComment,
   utils::is_admin,
+  SuccessResponse,
 };
 use lemmy_db_schema::{
   source::{
@@ -19,7 +20,7 @@ pub async fn purge_comment(
   data: Json<PurgeComment>,
   context: Data<LemmyContext>,
   local_user_view: LocalUserView,
-) -> Result<Json<PurgeItemResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   // Only let admin purge an item
   is_admin(&local_user_view)?;
 
@@ -43,5 +44,5 @@ pub async fn purge_comment(
 
   AdminPurgeComment::create(&mut context.pool(), &form).await?;
 
-  Ok(Json(PurgeItemResponse { success: true }))
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/crates/api/src/site/purge/community.rs b/crates/api/src/site/purge/community.rs
index 6ca30125d85de9cae8a55af0a3667133280a3787..6b307a06e1b7cdce331e88fca3157efbe8158c56 100644
--- a/crates/api/src/site/purge/community.rs
+++ b/crates/api/src/site/purge/community.rs
@@ -2,8 +2,9 @@ use actix_web::web::{Data, Json};
 use lemmy_api_common::{
   context::LemmyContext,
   request::purge_image_from_pictrs,
-  site::{PurgeCommunity, PurgeItemResponse},
+  site::PurgeCommunity,
   utils::{is_admin, purge_image_posts_for_community},
+  SuccessResponse,
 };
 use lemmy_db_schema::{
   source::{
@@ -20,7 +21,7 @@ pub async fn purge_community(
   data: Json<PurgeCommunity>,
   context: Data<LemmyContext>,
   local_user_view: LocalUserView,
-) -> Result<Json<PurgeItemResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   // Only let admin purge an item
   is_admin(&local_user_view)?;
 
@@ -49,5 +50,5 @@ pub async fn purge_community(
 
   AdminPurgeCommunity::create(&mut context.pool(), &form).await?;
 
-  Ok(Json(PurgeItemResponse { success: true }))
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/crates/api/src/site/purge/person.rs b/crates/api/src/site/purge/person.rs
index 96b8f78593619ff702b0f83cb0c107e903a3343c..c59e069311751acba741eceeb3e0f1a78b920e67 100644
--- a/crates/api/src/site/purge/person.rs
+++ b/crates/api/src/site/purge/person.rs
@@ -2,8 +2,9 @@ use actix_web::web::{Data, Json};
 use lemmy_api_common::{
   context::LemmyContext,
   request::delete_image_from_pictrs,
-  site::{PurgeItemResponse, PurgePerson},
+  site::PurgePerson,
   utils::is_admin,
+  SuccessResponse,
 };
 use lemmy_db_schema::{
   source::{
@@ -21,7 +22,7 @@ pub async fn purge_person(
   data: Json<PurgePerson>,
   context: Data<LemmyContext>,
   local_user_view: LocalUserView,
-) -> Result<Json<PurgeItemResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   // Only let admin purge an item
   is_admin(&local_user_view)?;
 
@@ -48,5 +49,5 @@ pub async fn purge_person(
 
   AdminPurgePerson::create(&mut context.pool(), &form).await?;
 
-  Ok(Json(PurgeItemResponse { success: true }))
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/crates/api/src/site/purge/post.rs b/crates/api/src/site/purge/post.rs
index a7469aa904d00be699d663515e3380e6d0bc4395..68ef76001fad4e05e9ebb090ad161fd1697b775d 100644
--- a/crates/api/src/site/purge/post.rs
+++ b/crates/api/src/site/purge/post.rs
@@ -2,8 +2,9 @@ use actix_web::web::{Data, Json};
 use lemmy_api_common::{
   context::LemmyContext,
   request::purge_image_from_pictrs,
-  site::{PurgeItemResponse, PurgePost},
+  site::PurgePost,
   utils::is_admin,
+  SuccessResponse,
 };
 use lemmy_db_schema::{
   source::{
@@ -20,7 +21,7 @@ pub async fn purge_post(
   data: Json<PurgePost>,
   context: Data<LemmyContext>,
   local_user_view: LocalUserView,
-) -> Result<Json<PurgeItemResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   // Only let admin purge an item
   is_admin(&local_user_view)?;
 
@@ -51,5 +52,5 @@ pub async fn purge_post(
 
   AdminPurgePost::create(&mut context.pool(), &form).await?;
 
-  Ok(Json(PurgeItemResponse { success: true }))
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/crates/api_common/src/community.rs b/crates/api_common/src/community.rs
index 8e87ab750212c17976184686a44e773e6a9b0519..dab69e7112e140a3cabb0356cfb90353486de1ca 100644
--- a/crates/api_common/src/community.rs
+++ b/crates/api_common/src/community.rs
@@ -4,7 +4,7 @@ use lemmy_db_schema::{
   ListingType,
   SortType,
 };
-use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView, PersonView};
+use lemmy_db_views_actor::structs::{CommunityModeratorView, CommunityView};
 use serde::{Deserialize, Serialize};
 use serde_with::skip_serializing_none;
 #[cfg(feature = "full")]
@@ -100,15 +100,6 @@ pub struct BanFromCommunity {
   pub expires: Option<i64>,
 }
 
-#[derive(Debug, Serialize, Deserialize, Clone)]
-#[cfg_attr(feature = "full", derive(TS))]
-#[cfg_attr(feature = "full", ts(export))]
-/// The response for banning a user from a community.
-pub struct BanFromCommunityResponse {
-  pub person_view: PersonView,
-  pub banned: bool,
-}
-
 #[derive(Debug, Serialize, Deserialize, Clone, Default)]
 #[cfg_attr(feature = "full", derive(TS))]
 #[cfg_attr(feature = "full", ts(export))]
@@ -119,14 +110,6 @@ pub struct AddModToCommunity {
   pub added: bool,
 }
 
-#[derive(Debug, Serialize, Deserialize, Clone)]
-#[cfg_attr(feature = "full", derive(TS))]
-#[cfg_attr(feature = "full", ts(export))]
-/// The response of adding a moderator to a community.
-pub struct AddModToCommunityResponse {
-  pub moderators: Vec<CommunityModeratorView>,
-}
-
 #[skip_serializing_none]
 #[derive(Debug, Serialize, Deserialize, Clone, Default)]
 #[cfg_attr(feature = "full", derive(TS))]
@@ -200,16 +183,6 @@ pub struct BlockCommunity {
   pub block: bool,
 }
 
-#[skip_serializing_none]
-#[derive(Debug, Serialize, Deserialize, Clone)]
-#[cfg_attr(feature = "full", derive(TS))]
-#[cfg_attr(feature = "full", ts(export))]
-/// The block community response.
-pub struct BlockCommunityResponse {
-  pub community_view: CommunityView,
-  pub blocked: bool,
-}
-
 #[derive(Debug, Serialize, Deserialize, Clone, Default)]
 #[cfg_attr(feature = "full", derive(TS))]
 #[cfg_attr(feature = "full", ts(export))]
diff --git a/crates/api_common/src/custom_emoji.rs b/crates/api_common/src/custom_emoji.rs
index 83248dc91a932ae879b8234ff6cbd97aa41a2fe9..d2900853e77ae1572fe06e23e6ef166bc455f9ff 100644
--- a/crates/api_common/src/custom_emoji.rs
+++ b/crates/api_common/src/custom_emoji.rs
@@ -39,15 +39,6 @@ pub struct DeleteCustomEmoji {
   pub id: CustomEmojiId,
 }
 
-#[derive(Serialize, Deserialize, Clone)]
-#[cfg_attr(feature = "full", derive(TS))]
-#[cfg_attr(feature = "full", ts(export))]
-/// The response for deleting a custom emoji.
-pub struct DeleteCustomEmojiResponse {
-  pub id: CustomEmojiId,
-  pub success: bool,
-}
-
 #[derive(Debug, Serialize, Deserialize, Clone)]
 #[cfg_attr(feature = "full", derive(TS))]
 #[cfg_attr(feature = "full", ts(export))]
diff --git a/crates/api_common/src/person.rs b/crates/api_common/src/person.rs
index c067c37998c16c34d23f0b32ac9ad36602ddc737..9642821c43fe9b4cf3f7947da45f57e01a6254f8 100644
--- a/crates/api_common/src/person.rs
+++ b/crates/api_common/src/person.rs
@@ -193,14 +193,6 @@ pub struct AddAdmin {
   pub added: bool,
 }
 
-#[derive(Debug, Serialize, Deserialize, Clone)]
-#[cfg_attr(feature = "full", derive(TS))]
-#[cfg_attr(feature = "full", ts(export))]
-/// The response of current admins.
-pub struct AddAdminResponse {
-  pub admins: Vec<PersonView>,
-}
-
 #[skip_serializing_none]
 #[derive(Debug, Serialize, Deserialize, Clone, Default)]
 #[cfg_attr(feature = "full", derive(TS))]
@@ -224,15 +216,6 @@ pub struct BannedPersonsResponse {
   pub banned: Vec<PersonView>,
 }
 
-#[derive(Debug, Serialize, Deserialize, Clone)]
-#[cfg_attr(feature = "full", derive(TS))]
-#[cfg_attr(feature = "full", ts(export))]
-/// A response for a banned person.
-pub struct BanPersonResponse {
-  pub person_view: PersonView,
-  pub banned: bool,
-}
-
 #[derive(Debug, Serialize, Deserialize, Clone, Default)]
 #[cfg_attr(feature = "full", derive(TS))]
 #[cfg_attr(feature = "full", ts(export))]
@@ -242,15 +225,6 @@ pub struct BlockPerson {
   pub block: bool,
 }
 
-#[derive(Debug, Serialize, Deserialize, Clone)]
-#[cfg_attr(feature = "full", derive(TS))]
-#[cfg_attr(feature = "full", ts(export))]
-/// The response for a person block.
-pub struct BlockPersonResponse {
-  pub person_view: PersonView,
-  pub blocked: bool,
-}
-
 #[skip_serializing_none]
 #[derive(Debug, Serialize, Deserialize, Clone, Default)]
 #[cfg_attr(feature = "full", derive(TS))]
@@ -318,14 +292,6 @@ pub struct MarkCommentReplyAsRead {
   pub read: bool,
 }
 
-#[derive(Debug, Serialize, Deserialize, Clone)]
-#[cfg_attr(feature = "full", derive(TS))]
-#[cfg_attr(feature = "full", ts(export))]
-/// The response for a comment reply action.
-pub struct CommentReplyResponse {
-  pub comment_reply_view: CommentReplyView,
-}
-
 #[derive(Debug, Serialize, Deserialize, Clone, Default)]
 #[cfg_attr(feature = "full", derive(TS))]
 #[cfg_attr(feature = "full", ts(export))]
diff --git a/crates/api_common/src/site.rs b/crates/api_common/src/site.rs
index b047c6dd03e684adee9f33c7455fd67544a58883..a66f200407ee0d41879c9e687a19baeaf8ce348f 100644
--- a/crates/api_common/src/site.rs
+++ b/crates/api_common/src/site.rs
@@ -361,14 +361,6 @@ pub struct PurgeComment {
   pub reason: Option<String>,
 }
 
-#[derive(Serialize, Deserialize, Clone)]
-#[cfg_attr(feature = "full", derive(TS))]
-#[cfg_attr(feature = "full", ts(export))]
-/// The response for purged items.
-pub struct PurgeItemResponse {
-  pub success: bool,
-}
-
 #[skip_serializing_none]
 #[derive(Debug, Serialize, Deserialize, Clone, Default)]
 #[cfg_attr(feature = "full", derive(TS))]
@@ -424,11 +416,3 @@ pub struct BlockInstance {
   pub instance_id: InstanceId,
   pub block: bool,
 }
-
-#[skip_serializing_none]
-#[derive(Debug, Serialize, Deserialize, Clone)]
-#[cfg_attr(feature = "full", derive(TS))]
-#[cfg_attr(feature = "full", ts(export))]
-pub struct BlockInstanceResponse {
-  pub blocked: bool,
-}
diff --git a/crates/api_crud/src/custom_emoji/delete.rs b/crates/api_crud/src/custom_emoji/delete.rs
index 44cddd52017747880169f855a33c7d4df795a427..93c5f8d80b95763af62df41fbf2357f4d0773b96 100644
--- a/crates/api_crud/src/custom_emoji/delete.rs
+++ b/crates/api_crud/src/custom_emoji/delete.rs
@@ -2,8 +2,9 @@ use activitypub_federation::config::Data;
 use actix_web::web::Json;
 use lemmy_api_common::{
   context::LemmyContext,
-  custom_emoji::{DeleteCustomEmoji, DeleteCustomEmojiResponse},
+  custom_emoji::DeleteCustomEmoji,
   utils::is_admin,
+  SuccessResponse,
 };
 use lemmy_db_schema::source::custom_emoji::CustomEmoji;
 use lemmy_db_views::structs::LocalUserView;
@@ -14,12 +15,11 @@ pub async fn delete_custom_emoji(
   data: Json<DeleteCustomEmoji>,
   context: Data<LemmyContext>,
   local_user_view: LocalUserView,
-) -> Result<Json<DeleteCustomEmojiResponse>, LemmyError> {
+) -> Result<Json<SuccessResponse>, LemmyError> {
   // Make sure user is an admin
   is_admin(&local_user_view)?;
+
   CustomEmoji::delete(&mut context.pool(), data.id).await?;
-  Ok(Json(DeleteCustomEmojiResponse {
-    id: data.id,
-    success: true,
-  }))
+
+  Ok(Json(SuccessResponse::default()))
 }
diff --git a/scripts/test.sh b/scripts/test.sh
index 2a5efb30d10d5a825cc7ff8fa23e53107a39d744..cdfbf7611cd083153f995df4f35905babdb43282 100755
--- a/scripts/test.sh
+++ b/scripts/test.sh
@@ -22,6 +22,9 @@ else
   cargo test --workspace --no-fail-fast
 fi
 
+# Testing lemmy utils all features in particular (for ts-rs bindings)
+cargo test -p lemmy_utils --all-features --no-fail-fast
+
 # Add this to do printlns: -- --nocapture
 
 pg_ctl stop