-
Notifications
You must be signed in to change notification settings - Fork 1
Steam Static Assets
Steam has many useful public image and media resources around AppIDs and player SteamIDs.
They are not all exposed through one official Web API method, and they are not all stored under the same host or path shape. Some assets can be built from an AppID, while others require a hash or a URL returned by Storefront or player metadata.
addons/assets exists to make this easier for Go developers.
It provides small helpers for building common public Steam Store and Library static asset URLs, resolving Storefront and player/Profile media URLs, verifying whether URLs exist, reading resources into memory, downloading files, and writing asset manifests.
This page explains:
- what kinds of public Steam static resources developers usually need
- where those resources are commonly requested from
- what can be built from only an AppID
- what requires a hash or Storefront metadata
- which player assets are discovered from Steam-returned URLs
- how
steam-go/addons/assetshelps with these resources - what the addon intentionally does not do
This page is not a legal or licensing statement. Always follow Steam's terms, Steamworks rules, and your own product requirements when using Steam-hosted assets.
Steamworks groups graphical assets into several broad families.
| Family | Common use | Examples |
|---|---|---|
| Store assets | Store pages, search results, recommendations, sales surfaces | header capsule, small capsule, main capsule, screenshots, page background |
| Library assets | Steam client library presentation | library capsule, library hero, library logo, library header |
| Community and client icons | Steam Community and Steam client compact presentation | App icon JPG, shortcut/client icon ICO or PNG |
| Storefront media | Media returned by Store appdetails | screenshots, movie thumbnails, WebM/MP4/HLS/DASH URLs, backgrounds |
| Player and Profile assets | Public player presentation | avatars, Profile backgrounds, mini-profile backgrounds, avatar frames, animated-avatar images and videos |
Steamworks documentation describes Store assets, Library assets, and Community / Client icons separately:
- Store graphical assets: https://partner.steamgames.com/doc/store/assets/standard
- Library assets: https://partner.steamgames.com/doc/store/assets/libraryassets
- Community and client icons: https://partner.steamgames.com/doc/store/assets/community
- Graphical assets overview: https://partner.steamgames.com/doc/store/assets
In practice, developers usually see these public resource hosts:
| Host | Typical use |
|---|---|
shared.steamstatic.com |
Store and Library static assets such as header.jpg, library_600x900_2x.jpg, library_hero.jpg, and logo_2x.png
|
shared.akamai.steamstatic.com |
Akamai-backed shared static resource CDN host |
shared.cloudflare.steamstatic.com |
Cloudflare-backed shared static resource CDN host |
cdn.cloudflare.steamstatic.com |
Steam Community and client image resources, often with AppID/hash-based paths |
shared.fastly.steamstatic.com |
CDN host that may appear in returned URLs or browser-observed URLs |
shared.st.dl.eccdnx.com |
Steam China shared static resource CDN host |
shared.cdn.steamchina.queniuam.com |
Steam China shared static resource CDN host |
addons/assets uses https://shared.steamstatic.com as the canonical static asset base for locally constructed Store and Library URLs.
assets.StaticCDNBaseURLs() returns the known shared static CDN base URLs in the table above. assets.StaticStoreItemAssetBaseURLs() appends store_item_assets/ when callers want Store item asset prefixes for each CDN.
It also builds community/client icon URLs under:
https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/{appid}/{hash}.{ext}
Do not assume every Steam CDN host follows the same path behavior forever. Prefer URLs returned by Steam metadata when available, and verify guessed URLs when existence matters.
Many high-value Store and Library assets can be built from only an AppID.
For AppID 107100, common examples include:
https://shared.steamstatic.com/store_item_assets/steam/apps/107100/header.jpg
https://shared.steamstatic.com/store_item_assets/steam/apps/107100/library_600x900_2x.jpg
https://shared.steamstatic.com/store_item_assets/steam/apps/107100/library_hero.jpg
https://shared.steamstatic.com/store_item_assets/steam/apps/107100/logo_2x.png
addons/assets exposes these as typed asset kinds.
addons/assets kind |
File name |
|---|---|
assets.KindHeader |
header.jpg |
assets.KindHeaderLocalized |
header_{language}.jpg |
assets.KindCapsuleSmall |
capsule_231x87.jpg |
assets.KindCapsuleMain |
capsule_616x353.jpg |
assets.KindLibraryCapsule |
library_600x900.jpg |
assets.KindLibraryCapsule2x |
library_600x900_2x.jpg |
assets.KindLibraryHero |
library_hero.jpg |
assets.KindLibraryLogo |
logo.png |
assets.KindLibraryLogo2x |
logo_2x.png |
These helpers are local URL builders. They do not call Steam by themselves.
Newer Steam games may use hashed Store item asset paths that cannot be derived from the AppID alone:
https://shared.steamstatic.com/store_item_assets/steam/apps/4710650/448851b668e4397d9863e571cf481b0e46e1315f/library_hero_2x.jpg
Use FetchStoreItemAssetURLs when you need those official hashed URLs. It uses
client.API.StoreBrowseService.GetItems with data_request.include_assets=true
and resolves Steam's returned asset_url_format.
client, err := steam.NewClient(steam.WithSafeDefaults())
if err != nil {
return err
}
defer client.Close()
items, err := assets.FetchStoreItemAssetURLs(ctx, client.API.StoreBrowseService, assets.StoreItemAssetOptions{
CountryCode: "US",
Language: "english",
Kinds: []assets.Kind{
assets.KindHeader2x,
assets.KindLibraryCapsule2x,
assets.KindLibraryHero2x,
},
}, 4710650)
if err != nil {
return err
}
for _, item := range items {
fmt.Println(item.AppID, item.Kind, item.URL, item.Digest, item.Filename, item.Source)
}This path is intentionally separate from FetchStoreMediaURLs. Store item assets
cover Store/Library images such as headers, capsules, library hero, logo, page
background, and community icon. Storefront media covers screenshots, movies, and
Storefront backgrounds returned by appdetails.
By default, Steam's returned query string such as ?t= is preserved. Set
StoreItemAssetOptions.StripQuery only when your downstream storage deliberately
does not want cache-version query parameters.
Community and client icon URLs require a known hash.
Examples:
https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/107100/8377b4460f19465c261673f76f2656bdb3288273.jpg
https://cdn.cloudflare.steamstatic.com/steamcommunity/public/images/apps/107100/ad7f9414231a7a5bb96d74e21893a84972dcbee8.ico
The hash is not derived from the AppID by addons/assets.
It must come from another source, such as Steam-owned game metadata, appinfo/client metadata, or another trusted source available to the caller. The addon only builds the final URL once the caller already has the AppID/hash pair.
icon := assets.CommunityIconURL(
107100,
"8377b4460f19465c261673f76f2656bdb3288273",
)
clientIcon := assets.ClientIconURL(
107100,
"ad7f9414231a7a5bb96d74e21893a84972dcbee8",
)Related kinds:
addons/assets kind |
Meaning |
|---|---|
assets.KindCommunityIconJPG |
community/app icon JPG when a hash is known |
assets.KindCommunityLogoJPG |
community/logo JPG when a hash is known |
assets.KindClientIconICO |
client shortcut icon ICO when a hash is known |
Some useful media is better resolved from Storefront appdetails instead of guessed from a static path.
addons/assets can request Storefront appdetails through the existing client.Web.Storefront service and extract:
- Store page background
- raw Store page background
- screenshot thumbnails
- full screenshots
- movie thumbnails
- movie WebM URLs
- movie MP4 URLs
- movie DASH/HLS playlist URLs
These are represented by Store media kinds such as:
assets.KindStoreBackground
assets.KindStoreBackgroundRaw
assets.KindScreenshotThumbnail
assets.KindScreenshotFull
assets.KindMovieThumbnail
assets.KindMovieWebM480
assets.KindMovieWebMMax
assets.KindMovieMP4480
assets.KindMovieMP4Max
assets.KindMovieDASHAV1
assets.KindMovieDASHH264
assets.KindMovieHLSH264DASH/HLS helpers return the playlist or manifest URL itself. The addon does not expand playlists into video segments.
Player assets are discovered from Steam-returned URLs rather than constructed from a SteamID, avatar hash, or Profile item ID:
-
FetchPlayerAvatarURLsuses theavatar,avatarmedium, andavatarfullURLs returned by officialISteamUser/GetPlayerSummaries/v2. -
FetchEquippedProfileAssetURLsreturns equipped Profile backgrounds, mini-profile backgrounds, avatar frames, and animated-avatar image/WebM/MP4 URLs fromIPlayerService/GetProfileItemsEquipped/v1.
avatars, err := assets.FetchPlayerAvatarURLs(
ctx,
client.API.SteamUser,
assets.PlayerAvatarOptions{},
"76561198000000000",
)
profile, err := assets.FetchEquippedProfileAssetURLs(
ctx,
client.API.PlayerService,
assets.PlayerProfileAssetOptions{Language: "english"},
"76561198000000000",
)The PlayerService method is a currently observed surface that is not listed in
Valve's public Web API reference. Relative paths without a returned host and
empty fields are skipped. Verify, read, and download helpers preserve optional
SteamID metadata; downloads use <Dir>/<SteamID>/<kind>.<ext>.
Import the addon:
import "github.com/gofurry/steam-go/addons/assets"Build simple URLs:
headers := assets.HeaderURLs(550, 107100)
heroes := assets.URLs(assets.KindLibraryHero, 550, 107100)
logos := assets.LibraryLogo2xURLs(550, 107100)Build one struct per AppID:
all := assets.AllWithLanguage("schinese", 550, 107100)
for _, item := range all {
fmt.Println(item.AppID, item.Header, item.LibraryHero, item.LibraryLogo2x)
}Build a flat list of typed URL items:
items := assets.ListKindsWithLanguage(
"schinese",
[]assets.Kind{
assets.KindHeader,
assets.KindHeaderLocalized,
assets.KindLibraryCapsule2x,
assets.KindLibraryHero,
assets.KindLibraryLogo2x,
},
550,
107100,
)Not every AppID has every asset.
Use verification when existence matters:
results, err := assets.VerifyAppAssets(ctx, assets.VerifyAppOptions{
Kinds: []assets.Kind{
assets.KindHeader,
assets.KindLibraryHero,
assets.KindLibraryLogo2x,
},
Language: "schinese",
}, 550, 107100)
if err != nil {
return err
}
for _, result := range results {
fmt.Println(result.AppID, result.Kind, result.Exists, result.StatusCode)
}For direct URLs:
results, err := assets.VerifyURLsWithOptions(ctx, assets.VerifyOptions{
URLValidator: assets.SteamStaticURLValidator,
}, "https://shared.steamstatic.com/store_item_assets/steam/apps/550/header.jpg")VerifyURLs uses HEAD first and falls back to GET when the server returns 405 or 501. HTTP non-2xx responses are reported as Exists=false rather than treated as hard errors.
For small batches:
results, err := assets.ReadAppAssets(ctx, assets.ReadAppOptions{
Kinds: []assets.Kind{assets.KindHeader, assets.KindLibraryHero},
MaxBytes: 8 << 20,
}, 550)For large batches, prefer streaming one result at a time:
err := assets.ReadEachAppAssets(ctx, assets.ReadAppOptions{
Kinds: []assets.Kind{assets.KindHeader},
Concurrency: 4,
}, func(result assets.ReadResult) error {
if result.Error != "" {
fmt.Println("failed:", result.URL, result.Error)
return nil
}
fmt.Println("read", result.URL, result.BytesRead)
return nil
}, 550, 107100)ReadURLs defaults to a 32 MiB per-resource limit. Set MaxBytes deliberately for larger resources.
Download generated AppID assets:
results, err := assets.DownloadAppAssets(ctx, assets.DownloadAppOptions{
Dir: "./tmp/assets",
Mode: assets.StoreByAppID,
Language: "schinese",
Kinds: []assets.Kind{assets.KindHeader, assets.KindLibraryHero, assets.KindLibraryLogo2x},
SkipExisting: true,
Concurrency: 4,
}, 550, 107100)Download modes:
| Mode | Behavior |
|---|---|
assets.StoreFlat |
writes generated files directly under the destination directory, with AppID-prefixed names such as 550_header.jpg
|
assets.StoreByAppID |
writes files under child folders such as 550/header.jpg
|
Download results include:
DownloadStatusDownloadedDownloadStatusSkippedDownloadStatusFailed
Batch downloads try every URL. Successful files remain on disk even when later items fail.
Storefront media uses the existing client.Web.Storefront service.
client, err := steam.NewClient(steam.WithSafeDefaults())
if err != nil {
return err
}
defer client.Close()
items, err := assets.FetchStoreMediaURLs(ctx, client.Web.Storefront, assets.StoreMediaOptions{
Language: "schinese",
Kinds: []assets.Kind{
assets.KindScreenshotFull,
assets.KindMovieThumbnail,
assets.KindStoreBackground,
},
}, 550)
if err != nil {
return err
}
for _, item := range items {
fmt.Println(item.AppID, item.Kind, item.ID, item.Name, item.URL)
}You can also verify, read, or download Storefront media:
verified, err := assets.VerifyStoreMedia(ctx, client.Web.Storefront, assets.VerifyStoreMediaOptions{
Language: "schinese",
}, 550)results, err := assets.DownloadStoreMedia(ctx, client.Web.Storefront, assets.DownloadStoreMediaOptions{
Dir: "./tmp/store-media",
Mode: assets.StoreByAppID,
Kinds: []assets.Kind{assets.KindScreenshotFull, assets.KindMovieThumbnail},
Concurrency: 4,
}, 550)Manifests are useful for crawlers, build pipelines, bots, and frontend indexing.
items := assets.ListWithLanguage("schinese", 550, 107100)
manifest := assets.NewURLManifest(items)
if err := assets.WriteManifestJSON("./tmp/assets/manifest.json", manifest); err != nil {
return err
}For downloads:
results, err := assets.DownloadAppAssets(ctx, opts, 550, 107100)
if err != nil {
fmt.Println("some downloads failed:", err)
}
manifest := assets.NewDownloadManifest(results)
_ = assets.WriteManifestJSON("./tmp/assets/download-manifest.json", manifest)Some helpers accept direct caller-supplied URLs:
VerifyURLsReadURLsDownloadURLs
If those URLs come from users or another untrusted source, set a validator before sending HTTP requests.
results, err := assets.ReadURLsWithOptions(ctx, assets.ReadOptions{
URLValidator: assets.SteamStaticURLValidator,
}, urls...)Available validators:
assets.AllowHosts("shared.steamstatic.com")
assets.AllowHostSuffixes("steamstatic.com")
assets.SteamStaticURLValidatorSteamStaticURLValidator accepts hosts under steamstatic.com. Use stricter validators when your application needs stricter host controls.
It also accepts the known Steam China shared static CDN hosts returned by assets.StaticCDNBaseURLs().
addons/assets intentionally stays small.
It does not:
- create a
steam.Client - integrate SteamGridDB
- parse Steam client appinfo
- discover client icon hashes by itself
- scrape Steam Community HTML or guess player asset CDN paths
- guarantee that every generated URL exists
- expand DASH/HLS playlists into video segments
- treat public static URLs as official stable Web API endpoints
It is a practical toolkit for constructing, validating, reading, and downloading public Steam asset resources.
- Build AppID-only static Store and Library URLs when you need predictable image candidates.
- Verify generated URLs before showing or downloading them in production workflows.
- Use Storefront media helpers for screenshots, movies, and backgrounds because those are better discovered from appdetails.
- Keep hash-based community/client icon handling separate from AppID-only URL construction.
- For large batches, use low concurrency and streaming read helpers.
- Keep manifests so downstream jobs know exactly which URLs were resolved and which downloads succeeded.
- Prefer URLs returned by Steam metadata when available.
- Treat the observed equipped-Profile surface as more volatile than the official player-summary avatar path.
- Treat Steam static resource paths as public resources, not as an official enumeration API.
The repository includes an example command:
go run ./examples/assets -app-ids 550,107100 -language schineseVerify generated app assets:
go run ./examples/assets -verify-apps -kind allDownload generated assets:
go run ./examples/assets \
-download-apps \
-download-dir ./tmp/assets \
-download-mode by_app_id \
-kind all \
-skip-existing \
-concurrency 4 \
-manifest ./tmp/assets/manifest.jsonFetch Storefront media:
go run ./examples/assets -app-ids 550 -store-media -kind allInspect and optionally verify player assets (requires configured Steam credentials):
go run ./examples/live/playerassets -verify
____ ____ ____ _ _ ____ ____ _ _ / ____ ___ ____ ____ _ _ ____ ____
| __ | | |___ | | |__/ |__/ \_/ / [__ | |___ |__| |\/| __ | __ | |
|__] |__| | |__| | \ | \ | / ___] | |___ | | | | |__] |__|
- SteamID Model
- Steam Web API Notes
- Public Store Page Access Notes
- Partner API Notes
- OpenID Notes
- A2S Notes
- Steam Keys and Access Tokens
- Steam Static Assets
- Steam VDF and addons/vdf
- Steam Web API 特性说明
- 公开商店页面访问说明
- Partner API 说明
- OpenID 说明
- A2S 说明
- Steam Key 与 Access Token
- Steam 静态资源
- Steam VDF 与 addons/vdf