# Changes to /admin/users/list/all.json API response structure?

**URL:** https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629
**Category:** Development
**Tags:** rest-api
**Created:** [May 11, 2025, 9:38am UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629 "2025-05-11T09:38:47Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Richie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/richie/32/115110_2.png) [@Richie](https://meta.discourse.org/u/Richie)
#### Post date: [May 11, 2025, 9:38am UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/1 "2025-05-11T09:38:47Z")

</div>

Currently running Discourse 3.5.0.beta5-dev ([eff31e0d42](https://github.com/discourse/discourse/commits/eff31e0d42c535ee115317f5b63ff70d90097911)).

Would anyone know if the API response from the /admin/users/list/all.json endpoint has changed in the last week or so? 🤔

Specifically:

`GET /admin/users/list/all.json?email=email@example.com`

🤔

I think this endpoint used to return a flat JSON object directly representing a single user when queried with an exact email address.

However, the current response structure now appears to wrap the user object inside a new `users` array, which has broken a few existing SSO integrations at our end.

Here is an anonymised pseudo example of the response of what I think has changed “before” and “after” for reference.

Old:

```json
{
  "id": 1,
  "username": "sampleuser",
  "name": "",
  "avatar_template": "/user_avatar/example.com/sampleuser/{size}/avatar.png",
  "active": true,
  "admin": false,
  "moderator": false,
  "last_seen_at": "2025-05-11T08:27:28.578Z",
  "created_at": "2020-01-01T12:00:00.000Z",
  "suspended": false,
  "trust_level": 1
}

```

New:

```json
{
  "users": [
    {
      "id": 1,
      "username": "sampleuser",
      "name": "",
      "avatar_template": "/user_avatar/example.com/sampleuser/{size}/avatar.png",
      "email": "someone@example.com",
      "active": true,
      "admin": false,
      "moderator": false,
      "last_seen_at": "2025-05-11T09:34:35.900Z",
      "created_at": "2020-01-01T12:00:00.000Z",
      "suspended": false,
      "trust_level": 1
    }
  ],
  "meta": {
    "message_bus_last_ids": {
      "bulk_delete": 0
    }
  }
}

```

Would anyone know of a recent commit that may have caused this change? 🤔

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [May 11, 2025, 11:09am UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/3 "2025-05-11T11:09:03Z")

</div>

It indeed changed and the commit is [this](https://github.com/discourse/discourse/commit/b6aad28ccffc276153fe847621d282549c4aac78)

```plaintext
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 92d906f161..70406efce5 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -32,7 +32,16 @@ class Admin::UsersController < Admin::StaffController
   def index
     users = ::AdminUserIndexQuery.new(params).find_users
 
- opts = { include_can_be_deleted: true, include_silence_reason: true }
+ opts = {
+ include_can_be_deleted: true,
+ include_silence_reason: true,
+ root: :users,
+ meta: {
+ message_bus_last_ids: {
+ bulk_delete: MessageBus.last_id("/bulk-user-delete"),
+ },
+ },
+ }
     if params[:show_emails] == "true"
       StaffActionLogger.new(current_user).log_show_emails(users, context: request.path)
       opts[:emails_desired] = true

```

---

<div class="post-metadata">

### Author: ![Richie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/richie/32/115110_2.png) [@Richie](https://meta.discourse.org/u/Richie)
#### Post date: [May 11, 2025, 11:52am UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/4 "2025-05-11T11:52:41Z")

</div>

No amount of searching through the 73x commits I updated with yesterday found this `DEV: replace selenium driver with playwright ` breaking change.

Thanks for the link @RGJ

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [May 11, 2025, 12:10pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/5 "2025-05-11T12:10:24Z")

</div>

> [@Richie](#):
>
> searching through the 73x commits

My approach:

- load `/admin/users/list/all.json?email=email@example.com`
- check the `x-discourse-route` header
- look up the corresponding file (`app/controllers/admin/users_controller.rb`)
- look up the corresponding method (`index`)
- press “Blame”
- spot the commit

 ![image](https://global.discourse-cdn.com/meta/original/4X/2/9/2/292a31488fec7e619c0316dafa07c39c5625109d.png)

---

<div class="post-metadata">

### Author: ![Richie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/richie/32/115110_2.png) [@Richie](https://meta.discourse.org/u/Richie)
#### Post date: [May 11, 2025, 12:27pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/6 "2025-05-11T12:27:22Z")

</div>

Nooooo way… 😱

Well, that’s what I learnt today!

Thanks @RGJ 👏🏻🤩

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [May 11, 2025, 12:32pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/7 "2025-05-11T12:32:08Z")

</div>

I managed to find that commit somehow, but couldn’t (and still don’t) see where it changed the data structure (I was on my phone, making things a bit more difficult).

---

<div class="post-metadata">

### Author: ![Richie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/richie/32/115110_2.png) [@Richie](https://meta.discourse.org/u/Richie)
#### Post date: [May 11, 2025, 2:50pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/8 "2025-05-11T14:50:29Z")

</div>

I’m guessing this was the breaking change in the API response 😕

In `/app/assets/javascripts/admin/addon/controllers/admin-users-list-show.js`

 ![Screenshot 2025-05-11 at 15.36.17](https://global.discourse-cdn.com/meta/original/4X/9/7/d/97dbcf2891428b8f0c1d8a04808f26bcb3cf56ce.png)

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [May 11, 2025, 3:12pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/9 "2025-05-11T15:12:51Z")

</div>

> [@pfaffman](#):
>
> where it changed the data structure

It’s the line `root: :users` that was added.

---

<div class="post-metadata">

### Author: ![Richie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/richie/32/115110_2.png) [@Richie](https://meta.discourse.org/u/Richie)
#### Post date: [May 11, 2025, 7:01pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/10 "2025-05-11T19:01:34Z")

</div>

We’ve now recovered from the impact of this change.

Perhaps going a bit off topic here but is there a way I can track these types of updates so I can notify myself when an API response changes from “X”, after being “Y” for so many years? 🤔

Some kind of scripted local unit tests that I could run on a daily basis perhaps?

Although now I’ve said that out loud, that wouldn’t notify me until _after_ I’d updated my Discourse and it had broken the integrations.

A staging environment I guess…

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [May 11, 2025, 7:26pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/11 "2025-05-11T19:26:22Z")

</div>

You could have a staging environment. You might also create a github action for your code that starts discourse and runs a test against the latest discourse each day.

---

<div class="post-metadata">

### Author: ![Richie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/richie/32/115110_2.png) [@Richie](https://meta.discourse.org/u/Richie)
#### Post date: [May 11, 2025, 8:00pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/12 "2025-05-11T20:00:53Z")

</div>

> [@pfaffman](#):
>
> runs a test against the latest discourse each day

Ah-ha! Perfect, that’d work, thanks 😁

---

<div class="post-metadata">

### Author: ![pfaffman](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/pfaffman/32/120154_2.png) [@pfaffman](https://meta.discourse.org/u/pfaffman)
#### Post date: [May 11, 2025, 8:42pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/13 "2025-05-11T20:42:47Z")

</div>

I think a plugin that called the endpoint and rendered it could be an easy way to test. And then change the default github action to run daily instead of only on push.

---

<div class="post-metadata">

### Author: ![RGJ](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/rgj/32/523185_2.png) [@RGJ](https://meta.discourse.org/u/RGJ)
#### Post date: [May 11, 2025, 9:27pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/14 "2025-05-11T21:27:01Z")

</div>

Seems the documentation needs an update as well [https://docs.discourse.org/#tag/Admin/operation/adminListUsers](https://docs.discourse.org/#tag/Admin/operation/adminListUsers)

In an ideal world, the documentation would be auto generated from the source and we could just look at the commit history for the documentation, which would only contain the changes in the interface.

---

<div class="post-metadata">

### Author: ![Richie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/richie/32/115110_2.png) [@Richie](https://meta.discourse.org/u/Richie)
#### Post date: [May 11, 2025, 9:51pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/15 "2025-05-11T21:51:30Z")

</div>

> [@RGJ](#):
>
> Seems the documentation needs an update as well

This is what caught me out too when trying to resolve the issues caused by this change 😕

---

<div class="post-metadata">

### Author: ![mjkkirschner](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/mjkkirschner/32/262148_2.png) [@mjkkirschner](https://meta.discourse.org/u/mjkkirschner)
#### Post date: [May 14, 2025, 9:56pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/16 "2025-05-14T21:56:14Z")

</div>

this has also broken an integration we have - is this something that we should anticipate being reverted?

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [May 15, 2025, 4:37pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/19 "2025-05-15T16:37:06Z")

</div>

Hi, yes sorry this shouldn’t have been merged, it was my mistake.

But the good news is that I already reverted it 8 hours ago: [DEV: revert admin users list change (#32723) · discourse/discourse@7558e2c · GitHub](https://github.com/discourse/discourse/commit/7558e2c7cd66306bf3ac33e0854a855ad11a26d5)

---

<div class="post-metadata">

### Author: ![Richie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/richie/32/115110_2.png) [@Richie](https://meta.discourse.org/u/Richie)
#### Post date: [May 15, 2025, 4:58pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/20 "2025-05-15T16:58:10Z")

</div>

Nooooooooo… _(repeat to fade)_

> [@j.jaffeux](#):
>
> the good news is

This is terrible news 😢

We’ll have to change all our integrations yet again 🤯

---

<div class="post-metadata">

### Author: ![j.jaffeux](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/j.jaffeux/32/60297_2.png) [@j.jaffeux](https://meta.discourse.org/u/j.jaffeux)
#### Post date: [May 15, 2025, 5:30pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/21 "2025-05-15T17:30:42Z")

</div>

sorry about that, sadly I had no choice but to revert, you got caught on an infortunate timing.

---

<div class="post-metadata">

### Author: ![merefield](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/merefield/32/176214_2.png) [@merefield](https://meta.discourse.org/u/merefield)
#### Post date: [May 15, 2025, 6:37pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/22 "2025-05-15T18:37:53Z")

</div>

A good reason to PR @Richie because then hopefully there’s a simple revert button.

---

<div class="post-metadata">

### Author: ![Richie](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/richie/32/115110_2.png) [@Richie](https://meta.discourse.org/u/Richie)
#### Post date: [May 15, 2025, 6:50pm UTC](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629/23 "2025-05-15T18:50:42Z")

</div>

> [@j.jaffeux](#):
>
> you got caught on an infortunate timing

This is the risk we take and the price we pay for living on the bleeding edge 😊

It still blows me away that Discourse is open source, it really does. Who am I to complain 🤷

Thank you for fixing the issue @j.jaffeux 👏 🙇

[Next page](https://meta.discourse.org/t/changes-to-admin-users-list-all-json-api-response-structure/365629.md?page=2)
