How to get asset Id from shirt object?

Yes.

or

1 Like

You can use the GetProductInfo method from the MarketplaceService, it returns a dictionary of all the information related to a product/asset. Including the AssetId.

https://developer.roblox.com/api-reference/function/MarketplaceService/GetProductInfo

2 Likes

OP is looking for a thumbnail, so that they can use this endpoint to retrieve its image. (At least that’s what I think they’re doing)

e.g.
https://www.roblox.com/asset-thumbnail/image?assetId=1127072005&width=420&height=420&format=png

Is the thumbnail for this shirt:

You can use the URL above in an ImageLabel in-game:


Since OP just wants to display what the player character is wearing, they can just retrieve the asset id that the character is wearing directly by reading the applied HumanoidDescription.

-- Assume that this is a script that's inside the player's character...
local Humanoid = script.Parent.Humanoid
local descriptionClone = Humanoid:GetAppliedDescription()
print(descriptionClone.Shirt) -- this is the asset id of the shirt that the player is wearing.
5 Likes

I did not read. :upside_down_face:

I believe the first thread can be ignored in that case, though wouldn’t IconImageAssetId from GetProductInfo also get the appropriate image as opposed to using the endpoint?

edit: wow i can’t see?

1 Like

IconImageAssetId is only for Developer Products.

3 Likes

It’s not possible. There was a feature request for something similar a while ago (decal asset id to image id) here:

One method is to keep subtracting the shirt template id by 1 until you get to its asset id… But this can take a lot of requests and the distance between the template to the asset id can be large (there are also more issues with this, read the feature request for more info).

7 Likes

Follow up: Is there any reason why using HumanoidDescriptions would be inconvenient?

1 Like

I have to rewrite my character customization module to use only HumanoidDescriptions :upside_down_face:

1 Like

Edit: I just remembered that you can’t issue HTTP requests to Roblox from in-game. I made a proxy for small batches of calls to this service. If this is for a small scale service, I can show you how to make a free proxy on Google Cloud Platform.

Assuming I understand the goal, it actually is possible. You have the Shirt Asset ID, and you want the Image Asset ID. Here’s what you do:

Issue an HTTP GET request to https://assetgame.roblox.com/asset/?id=SHIRT_ID
This will return XML for a Shirt Instance that you can parse to find the Image ID. For example:
http://assetgame.roblox.com/assets/?id=2551557116
will return:
<roblox xmlns:xmime="http://www.w3.org/2005/05/xmlmime" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.roblox.com/roblox.xsd" version="4"> <External>null</External> <External>nil</External> <Item class="Shirt" referent="RBX0"> <Properties> <Content name="ShirtTemplate"> <url>http://www.roblox.com/asset/?id=2551557110</url> </Content> <string name="Name">Shirt</string> <bool name="archivable">true</bool> </Properties> </Item> </roblox>

The line with the tag is what you are looking for. A simple string.match(responseBody, "<url>(.+)</url>") ought to do the trick.

This also works for Pants and Decals.

4 Likes

OP only has this to work with:

Your method won’t work on this.

1 Like

So the reverse, get a Shirt ID from an Image ID?

This is getting confusing. OP only has this to work with (let’s call this the ShirtTemplateId)

The ShirtTemplateId is 1127071991

OP wants to get the AssetId, which is 1127072005

How do you get from 1127071991 to 1127072005? It’s not possible without brute-forcing it. https://assetgame.roblox.com/asset/?id=1127071991 will get the image itself, not an xml.

2 Likes

I see. It’s still possible with a simple web app, in fact I already have one on GCP that does exactly this. It works somewhat like you are saying. It takes the as input a ShirtTemplateId. It increments it and uses Marketplace API (except the external version) and checks whether the asset is a Shirt. If it is, it uses the method I mentioned before to request that shirt’s corresponding ShirtTemplateId. If it matches, it returns the current incremented ID. If not, it continues incrementing.

… That’s brute-forcing it, which is literally the method I mentioned a few posts ago. Brute-forcing has some pitfalls that were mentioned in the feature request I mentioned, too. You don’t even need to use an external service for this, just use GetProductInfo.

You never described how to brute force it, and you also described it as “impossible”. It’s very possible.

Please don’t cherry-pick my wording…


1 Like

“until you get its asset id”

I guess what was missing is that you never described how you know when you’ve found the correct ID.

2 Likes

Just thought I’d reply to this thread cause I found myself with a similar problem and managed to find a solution. Posting this incase anyone in the future would be wondering the same thing.

local clothing_type = "Shirt" -- or "Pants"
local clothing_parent -- define this

local item_url = clothing_parent:FindFirstChildOfClass(clothing_type)[clothing_type .."Template"]

local ItemID = string.match(item_url, "%d+")

Roblox (Clothing) Asset URL’s come in two variants:

http://www.roblox.com/asset/?id=4979758466

rbxassetid://4979758466

the thing they have in common is that they both have numbers only at the end. So this method would be valid.

You could change the string manipulation used to define the ItemID, maybe to check for numbers in a different order, in case you want to apply this for other asset types.

Although, I think at that point there would be better API available to suit your goal.

5 Likes

Here’s something I wrote earlier that performs the reverse of what you’re trying to achieve (asset ID to catalog ID).

You should be able to repurpose the script for your particular use case.

I decided to modify the linked resource for you.

local marketplace = game:GetService"MarketplaceService"
local getProductInfo = marketplace.GetProductInfo

local assetTypeIds = {2, 11, 12, 13, 21} --T-Shirt, Shirt, Pants, Decal, Badge.
local maxTries = 5 --Maximum retries per catalog ID.
local maxHeight = 100 --Maximum height to search for.

local function getCatalogIdFromAssetId(assetId : number) : number
	local success, result = pcall(getProductInfo, marketplace, assetId)
	if success then
		if result then
			if result.AssetTypeId == 1 then
				local cache, success2, result2 = table.create(100), nil, nil
				repeat
					task.wait()
					assetId += 1
					if assetId - result.AssetId > maxHeight then
						return
					end
					if cache[assetId] then
						cache[assetId] += 1
					else
						cache[assetId] = 1
					end
					if cache[assetId] > maxTries then
						continue
					end
					success2, result2 = pcall(getProductInfo, marketplace, assetId)
					if not success2 then
						warn(result2)
						assetId -= 1
					end
				until result2 and table.find(assetTypeIds, result2.AssetTypeId) and result2.Creator.CreatorType == result.Creator.CreatorType and result2.Creator.CreatorTargetId == result.Creator.CreatorTargetId
				return result2.AssetId
			end
		end
	else
		warn(result)
	end
end

local assetId = getCatalogIdFromAssetId(14417331)
print(assetId) --14417332

The following image was used for testing purposes.
https://www.roblox.com/badges/14417332/John-Loved-of-Muses

1 Like

tonumber(string.sub(ShirtTemplate,32,99))