HTTP 403 (Forbidden) when making requests in regards of a different user

Hi there! I am currently developing a game that involves fetching the user information of in-game players using HttpService. I am currently using roproxy.com when performing these requests and have HTTP Requests and Studio Access to API services enabled. I am doing calls such as converting username to user ID and retrieving user’s collectible inventory from within a GUI. I am using Remote Functions in ReplicatedStorage and handling those functions inside of ServerScriptService.

Everything is working as I intended when I test it using my own username, “hierocrypt.” However, when I have my friend who is assisting me in development join and I test by clicking on his name (which passes his username as an argument to the function), it doesn’t work. It throws an HTTP 403 (Forbidden) error. I am sure that I am passing the correct arguments.

Some information that may be useful in debugging, the game is created under a group, the friend in question has full development permissions and access to assets (we tried revoking these permissions, didn’t change anything), we are currently on the same Wi-Fi (we tried using separate network connections, didn’t change anything), in the case that the user’s inventory is private we tried removing the collectibles requests and it still didn’t work. Also something to consider, we tested this from my friend’s device (on their account as well) where we passed my username (it worked) and we tried it on their username (it didn’t work). Here is the script used for handling the function calls (In ServerScriptService):

game.ReplicatedStorage.GetPlayerInfo.OnServerInvoke = function(player, url)
	local HttpService = game:GetService("HttpService")
	local response = HttpService:GetAsync(url)
	local data = HttpService:JSONDecode(response)
	if data.success == false then
		return nil
	else
		local collectibleResponse = HttpService:GetAsync(tostring("https://inventory.roproxy.com/v1/users/") .. tostring(data.Id) .. tostring("/assets/collectibles?assetType=Hat&sortOrder=Asc&limit=100"))
		local collectibleData = HttpService:JSONDecode(collectibleResponse)
		local userResponse = HttpService:GetAsync(tostring("https://users.roproxy.com/v1/users/" .. tostring(data.Id)))
		local userData = HttpService:JSONDecode(userResponse)
		local avatarResponse = HttpService:GetAsync("https://thumbnails.roproxy.com/v1/users/avatar-bust?userIds=" .. tostring(data.Id) .."&size=420x420&format=Png&isCircular=false")
		local avatarData = HttpService:JSONDecode(avatarResponse)
		return collectibleData, userData, avatarData
	end
end

Here is the local script being used to communicate with the remote function call (in StarterGUI):

playerInfoFrame = script.Parent.Parent.Parent.PlayerInfoFrame

script.Parent.MouseButton1Click:Connect(function()
	local collectibleData, userData, avatarData = game.ReplicatedStorage.GetPlayerInfo:InvokeServer("https://api.roproxy.com/users/get-by-username?username=" .. script.Parent.Name)	
	playerInfoFrame.UsernameLabel.Text = "Username: " .. userData.name
	playerInfoFrame.DisplayNameLabel.Text = "Display Name: " .. userData.displayName
	playerInfoFrame.AccountCreatedLabel.Text = "Account Created: " .. userData.created
	playerInfoFrame.UserIdLabel.Text = "User ID: " .. tostring(userData.id)
end)

The code can be cleaned up in some areas; however, I’m still playing around with ideas as of now. In the code snippet above, I am storing the returned values from the HTTP requests in three different variables (as the function returns three different variables) and appending the results to their corresponding TextLabels. Some values are unused, but they are still valid. As aforementioned, I’ve tested this using my own username as a parameter and it functioned properly; however, it didn’t when testing it on someone else. I’ve spent some time looking for people who have encountered the same issue but I have had no luck finding a thread that is of assistance to me. I’ve read multiple threads regarding developers encountering 403 errors, as well as all of the recommended topics that are similar to my post, but most have to do with Datastores/Discord or a completely different error code. I would greatly appreciate a hand, or a pointer in the right direction. Thank you!

1 Like

The error 403 means that the user’s inventory is not public and that endpoint for users who have hidden their inventory requires the roblosecurity cookie to authenticate the request and make sure that you are allowed to see the inventory.

Put the cookie in the headers

{
    'Cookie': '.ROBLOSEUCRITY=yourcookie'
}

also notice that you may face complications for this because ip changes invalidate the cookie

See Inventory Api

3 Likes

As aforementioned, I have attempted this without retrieving collectible inventory contents and still got a 403. So I don’t see how this could be the issue.

In the case that the user’s inventory being private was the issue, I can’t exactly obtain the user’s security cookie without violating TOS in someway.

Although I’m sure private inventories would come up in the future, I don’t plan on trying to access them. I would just be displaying something along the lines of “This user’s inventory is private.”

1 Like

By reading the docs you will see that the only endpoint of the ones you are using which can return error 403 is the inventory one

Thumbnails api - no 403 error

Users api - no 403 error

Inventory api - 403 error

2 Likes

Ah well, you were right. Their inventory was private, causing the 403. I must not have properly published after removing the collectible inventory request for testing, so that is my fault. Thank you very much for your help!

1 Like