diff --git a/api/custom/usage.go b/api/custom/usage.go
index 98f8af19423947598c2961b89b15e3bdd73c3e4e..8c37842d312384602b50c99c82c4151b0c1120e1 100644
--- a/api/custom/usage.go
+++ b/api/custom/usage.go
@@ -215,13 +215,18 @@ func GetUploadsUsage(r *http.Request, rctx rcontext.RequestContext, user api.Use
 
 // GetUsersUsageStats attempts to provide a loose equivalent to this Synapse admin end-point:
 // https://matrix-org.github.io/synapse/develop/admin_api/statistics.html#users-media-usage-statistics
-func GetUsersUsageStats(r *http.Request, rctx rcontext.RequestContext, _ api.UserInfo) interface{} {
+func GetUsersUsageStats(r *http.Request, rctx rcontext.RequestContext, user api.UserInfo) interface{} {
 	params := mux.Vars(r)
 	qs := r.URL.Query()
 	var err error
 
 	serverName := params["serverName"]
 
+	isGlobalAdmin, isLocalAdmin := api.GetRequestUserAdminStatus(r, rctx, user)
+	if !isGlobalAdmin && (!util.IsServerOurs(serverName) || !isLocalAdmin) {
+		return api.AuthFailed()
+	}
+
 	orderBy := qs.Get("order_by")
 	if len(qs["order_by"]) == 0 {
 		orderBy = "user_id"
diff --git a/api/webserver/webserver.go b/api/webserver/webserver.go
index 3e719b7d9ec38fe981459f2d046d30a1b671d414..fb9c7dd4f2a866799877a72e65d32450d11d8263 100644
--- a/api/webserver/webserver.go
+++ b/api/webserver/webserver.go
@@ -71,7 +71,7 @@ func Init() *sync.WaitGroup {
 	domainUsageHandler := handler{api.RepoAdminRoute(custom.GetDomainUsage), "domain_usage", counter, false}
 	userUsageHandler := handler{api.RepoAdminRoute(custom.GetUserUsage), "user_usage", counter, false}
 	uploadsUsageHandler := handler{api.RepoAdminRoute(custom.GetUploadsUsage), "uploads_usage", counter, false}
-	usersUsageStatsHandler := handler{api.RepoAdminRoute(custom.GetUsersUsageStats), "users_usage_stats", counter, false}
+	usersUsageStatsHandler := handler{api.AccessTokenRequiredRoute(custom.GetUsersUsageStats), "users_usage_stats", counter, false}
 	getBackgroundTaskHandler := handler{api.RepoAdminRoute(custom.GetTask), "get_background_task", counter, false}
 	listAllBackgroundTasksHandler := handler{api.RepoAdminRoute(custom.ListAllTasks), "list_all_background_tasks", counter, false}
 	listUnfinishedBackgroundTasksHandler := handler{api.RepoAdminRoute(custom.ListUnfinishedTasks), "list_unfinished_background_tasks", counter, false}
diff --git a/docs/admin.md b/docs/admin.md
index aaf70a7abfb9d880641501749c45a708dfc7ebfd..b35b4092e1bfc8eca8affa26a3adfa5e414d311e 100644
--- a/docs/admin.md
+++ b/docs/admin.md
@@ -171,7 +171,7 @@ The `task_id` can be given to the Background Tasks API described below.
 
 ## Data usage for servers/users
 
-Individual servers and users can often hoard data in the media repository. These endpoints will tell you how much. These endpoints can only be called by repository admins - they are not available to admins of the homeservers.
+Individual servers and users can often hoard data in the media repository. These endpoints will tell you how much. Unless stated otherwise (below), these endpoints can only be called by repository admins - they are not available to admins of the homeservers.
 
 **Caution**: These endpoints may return *lots* of data. Making very specific requests is recommended.
 
@@ -232,8 +232,11 @@ Use the same endpoint as above, but specifying one or more `?user_id=@alice:exam
 
 #### All known users' usage statistics
 
-Similar to [Per-user usage (all known users)](#per-user-usage-all-known-users), but with a focus on statistics, and with
-parameterized querying ability.
+Similar to [Per-user usage (all known users)](#per-user-usage-all-known-users), but with:
+
+* a focus on statistics
+* parameterized querying ability
+* relaxed authorization restrictions (to allow homeserver admins to query against their own homeserver)
 
 This end-point attempts to be a loose equivalent to
 [this](https://matrix-org.github.io/synapse/develop/admin_api/statistics.html#users-media-usage-statistics) Synapse