Upcoming Breaking Change to CheckUserBadgesAsync, UserHasBadgeAsync, and Badges Web APIs

Hello creators!

We are making changes to ensure that access to badge ownership information more consistently respects players’ privacy. These changes affect both engine BadgeService methods and badges web APIs, and will begin rolling out on March 23rd, 2026.

At a high level:

  • If your experience uses BadgeService to check badges from your own experience, the behavior should remain the same.
  • If your experience uses BadgeService to check badges from other experiences only for players that are (or have recently been) in the server, the behavior should remain the same.
  • If you are using UserHasBadgeAsync or CheckUserBadgesAsync to check badge ownership of badges from other experiences for users who have not recently been in the server, those checks will stop returning information after this change.
Experience owns the badge Experience does not own the badge
Player is in the server :white_check_mark: Still Allowed :white_check_mark: Still Allowed
Player is not in the server :white_check_mark: Still Allowed :cross_mark: No Longer Allowed

The rest of this announcement explains these changes in more detail.

This update changes the behavior of server-side calls to

  • BadgeService:UserHasBadgeAsync,
  • BadgeService:CheckUserBadgesAsync,

As well as the badge awarded date endpoints on badges.roblox.com

  • /v1/users/{userId}/badges/{badgeId}/awarded-date and
  • /v1/users/{userId}/badges/awarded-dates.

Today, these endpoints can be used to determine whether specific badges have been granted to any user ID. This causes privacy issues because a player cannot stop other users and experiences from inferring their play history from badge data.

Starting March 23rd, 2026, badge award information will be restricted as follows:

  • Requests from game servers (server-side BadgeService calls)
    When using UserHasBadgeAsync or CheckUserBadgesAsync:

    • If the user you’re checking was recently in the game server, the APIs will continue to return award information as they do today.
    • If the badge was created by the same experience that’s making the request, award information will also continue to be returned, even if the user has not recently been in the server.
    • In all other cases (checking badges created by other experiences for users who have not recently been in the server), the BadgeService methods will behave as if the badge has not been awarded, and information about those badges will not be included in responses.
  • Requests from clients (client-side BadgeService calls)
    Client calls to these BadgeService methods will continue to be restricted to the local player’s user ID. The behavior of client calls to these methods will not be impacted by these changes.

  • Requests to APIs from tools or scripts using Cookie Authentication
    For cookie‑authenticated calls to the awarded‑date endpoints:

    • The endpoints will now respect the target user’s inventory visibility settings to decide whether badges can be returned.
    • If the caller is not allowed to see that user’s badges under their inventory privacy settings, the awarded‑date endpoints will return empty results, as though none of the requested badges were awarded.
  • Unauthenticated Access
    Unauthenticated access to these badge awarded‑date endpoints will be disabled as part of this change, and will begin to return HTTP 401 Unauthorized.

If you are directly calling badges.roblox.com from external tools or services, we recommend migrating to the Open Cloud Badges and Inventory APIs. These Open Cloud endpoints support API keys and OAuth, and are being updated in step with these privacy principles. The access to, and behavior of, legacy cookie‑based endpoints may change over time.

If you have any questions or feedback about these changes, please comment below.
Thank you!

52 Likes

This topic was automatically opened after 10 minutes.

Wow, it seems like you have a lot of breaking changes coming out recently.

Do you overhaul an entire system or is there another reason why they come out now?

52 Likes

This is one of the major downsides of how public Roblox used to be.

Everything is now being restricted in the name of “privacy,” even in cases where privacy is not actually affected. Badges, for example, are not sensitive information.
The same applies to inventories.
They do not contain private or confidential data. Roblox does not expose personal or sensitive information through these systems.

By removing the ability to check badges, Roblox has reduced functionality that was genuinely useful. Badge visibility was an important tool for detecting and preventing badge exploits.
Limiting access to this information ultimately makes it harder for developers and community moderators to identify abuse and maintain integrity within their games.

84 Likes

I’m very curious for this specific case - what use cases were there that now break? Checking the badges of someone in the server makes sense (badge history or cross-game promotions, like Pressure), as well as offline players with badges in your game (friend activity), but what use cases were there for checking the badges of other experiences from people not in the experience?

12 Likes

I explained that right over.
To check the timestamp on when users are awarded the badges, in order to prevent exploits.

7 Likes

This is so we don’t check Matt Kaufman’s badges again, trust.

30 Likes

I bet he could easily squeeze them into his collar.

5 Likes

The horrors that I was expecting from the last breaking change that I asked about came into fruition.

6 Likes

I’m not sure what exploits you mean, but from what I understood you can still check badges for players just as long as they’re in the server.

8 Likes

I find this use case confusing. Why would you care about an exploiter who isn’t currently playing your game? If they are in your game you could check their badge history still.

If they are not then what are you going to do about them?

6 Likes

My point is that most people we check for badge exploiting aren’t even in the place.
Thus, not being able to check anymore.

9 Likes

Remote ban them, so they are permanently banned the next time they join the place.

5 Likes

What do you even mean by badge exploiting? What would you even be checking for?

7 Likes

Can you explain how you can use this for preventing exploits? I don’t see how you can tie another experience’s badges from before/after/between they played your experience to something useful for an exploiting metric.

17 Likes

The only thing I see is for games collaborating and somebody somehow obtaining badges before they’re supposed to, which is valid, but wouldn’t you be checking for that in the game anyway?

5 Likes

Will this functionality be linked to PromptInventoryAllowReadAccess? It would be really annoying for users to have to unprivate their inventory every time they need to check their badges for a multi-game badge challenge.

It would also be nice to see more granular privacy options, such as being able to hide my accessories/assets but not my earned badges, instead of both of these being under one toggle. The use cases for hiding each do not always overlap, such as for a developer wanting to hide their assets/accessories but still display their earned badges (perhaps if they both develop and play games)

17 Likes

This change stops you from even checking another user’s owned badges, from another person’s game.

Example1 yes you can list your 100 recent badges:
badges.roblox.com/v1/users/4309939/badges?limit=100&sortOrder=Asc

Not all devs check the time between each badges being awarded.
Normally roblox just rewards the badges.
So it’s up to each dev to implement it.
Thus, in other ways, moderators could use the Example2, in order to double check the timestamps.

Example2 where you list all the badges, from a specific game, to see if the user has gotten them, and at what time.

badges.roblox.com/v1/users/4309939/badges/awarded-dates?badgeIds=2128228806,2128228811,2128228812,2128228813,2128228816,2128228817,2128228819,2128228822,2128228824,2128228825,2128228830,2128228848,2128228861,2128229084,2128229517,2128229590,2128229869,2128229919,2128229989,2128230356,2128231045,2128231931,2128231938,2128231943,2128231946,2128231949,2128231951,2128231953,2128231958,2128231960,2128231963,2128231967,2128231970,2128231974,2128231975,2128231987,2128231993,2128232002,2128232011,2128232041,2128232042,2128232043,2129376698,2129376700

3 Likes

You should still be able to check it if they are in your game or were in it recently though, that shouldn’t prevent this use-case?

4 Likes

Define “recent”, i don’t trust this, roblox could define recent as 10 days, that’s a really short life span.
I also see no reason to break a feature, just because they want to.

4 Likes