diff --git a/integrations/api_admin_test.go b/integrations/api_admin_test.go
index b8dded9c11..a7bbde4c53 100644
--- a/integrations/api_admin_test.go
+++ b/integrations/api_admin_test.go
@@ -106,3 +106,26 @@ func TestAPISudoUserForbidden(t *testing.T) {
 	req := NewRequest(t, "GET", urlStr)
 	session.MakeRequest(t, req, http.StatusForbidden)
 }
+
+func TestAPIListUsers(t *testing.T) {
+	prepareTestEnv(t)
+	adminUsername := "user1"
+	session := loginUser(t, adminUsername)
+	token := getTokenForLoggedInUser(t, session)
+
+	urlStr := fmt.Sprintf("/api/v1/admin/users?token=%s", token)
+	req := NewRequest(t, "GET", urlStr)
+	resp := session.MakeRequest(t, req, http.StatusOK)
+	var users []api.User
+	DecodeJSON(t, resp, &users)
+
+	found := false
+	for _, user := range users {
+		if user.UserName == adminUsername {
+			found = true
+		}
+	}
+	assert.True(t, found)
+	numberOfUsers := models.GetCount(t, &models.User{}, "type = 0")
+	assert.Equal(t, numberOfUsers, len(users))
+}
diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go
index 2e2a7fecb9..609b53874e 100644
--- a/routers/api/v1/admin/user.go
+++ b/routers/api/v1/admin/user.go
@@ -10,6 +10,7 @@ import (
 	"code.gitea.io/gitea/modules/context"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
+	"code.gitea.io/gitea/routers/api/v1/convert"
 	"code.gitea.io/gitea/routers/api/v1/user"
 	api "code.gitea.io/sdk/gitea"
 )
@@ -319,8 +320,14 @@ func GetAllUsers(ctx *context.APIContext) {
 		PageSize: -1,
 	})
 	if err != nil {
-		ctx.Error(500, "SearchUsers", err)
+		ctx.Error(500, "GetAllUsers", err)
 		return
 	}
-	ctx.JSON(200, &users)
+
+	results := make([]*api.User, len(users))
+	for i := range users {
+		results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User.IsAdmin)
+	}
+
+	ctx.JSON(200, &results)
 }
diff --git a/routers/api/v1/convert/convert.go b/routers/api/v1/convert/convert.go
index 14344e581c..d9cc2da7a5 100644
--- a/routers/api/v1/convert/convert.go
+++ b/routers/api/v1/convert/convert.go
@@ -10,6 +10,7 @@ import (
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/git"
 	"code.gitea.io/gitea/modules/log"
+	"code.gitea.io/gitea/modules/markup"
 	"code.gitea.io/gitea/modules/util"
 	api "code.gitea.io/sdk/gitea"
 
@@ -216,3 +217,18 @@ func ToTeam(team *models.Team) *api.Team {
 		Units:       team.GetUnitNames(),
 	}
 }
+
+// ToUser convert models.User to api.User
+func ToUser(user *models.User, signed, admin bool) *api.User {
+	result := &api.User{
+		ID:        user.ID,
+		UserName:  user.Name,
+		AvatarURL: user.AvatarLink(),
+		FullName:  markup.Sanitize(user.FullName),
+		IsAdmin:   user.IsAdmin,
+	}
+	if signed && (!user.KeepEmailPrivate || admin) {
+		result.Email = user.Email
+	}
+	return result
+}
diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go
index 0f10c4e814..2e4ae273e5 100644
--- a/routers/api/v1/user/user.go
+++ b/routers/api/v1/user/user.go
@@ -10,7 +10,7 @@ import (
 
 	"code.gitea.io/gitea/models"
 	"code.gitea.io/gitea/modules/context"
-	"code.gitea.io/gitea/modules/markup"
+	"code.gitea.io/gitea/routers/api/v1/convert"
 	api "code.gitea.io/sdk/gitea"
 
 	"github.com/Unknwon/com"
@@ -67,16 +67,7 @@ func Search(ctx *context.APIContext) {
 
 	results := make([]*api.User, len(users))
 	for i := range users {
-		results[i] = &api.User{
-			ID:        users[i].ID,
-			UserName:  users[i].Name,
-			AvatarURL: users[i].AvatarLink(),
-			FullName:  markup.Sanitize(users[i].FullName),
-			IsAdmin:   users[i].IsAdmin,
-		}
-		if ctx.IsSigned && (!users[i].KeepEmailPrivate || ctx.User.IsAdmin) {
-			results[i].Email = users[i].Email
-		}
+		results[i] = convert.ToUser(users[i], ctx.IsSigned, ctx.User.IsAdmin)
 	}
 
 	ctx.JSON(200, map[string]interface{}{