Steam privacy and data availability
Steam profile visibility API: diagnose private and missing data
A public persona name, a public inventory and visible playtime are separate permissions. Read each WOK response as evidence for that specific surface, and keep unknown values separate from zero.
Updated
curl --fail-with-body --max-time 35 --get \
-H "Authorization: Bearer $WOK_API_KEY" \
--data-urlencode "steam_id=$STEAM_ID" \
"https://woksteamapi.com/v1/profile"Choose the response that answers your question
Start with a 17-digit SteamID64 in STEAM_ID. Each authenticated WOK data request uses one quota unit. Check only the surface your feature needs.
| Question | WOK endpoint | Interpretation |
|---|---|---|
| Can I show this persona? | GET /v1/profile | personaname and steamid identify the account. visibility=3 means Steam marked the profile public; a returned name alone does not prove that games or inventory are public. |
| Are this game's items exposed? | GET /v1/inventory | Read JSON status. private, empty and ok are different outcomes, even when items is empty. |
| Are games and hours exposed? | GET /v1/games | visibility=unknown with games=[] cannot distinguish private game details from a truly empty library. total_playtime_hours=null is unknown, not zero. |
| Can I read friends? | GET /v1/friends | HTTP 403 with friends_private means the public friend list is unavailable. Do not display an empty list as a verified result. |
| Can I read Rust statistics? | GET /v1/rust/summary | HTTP 403 with rust_data_unavailable means the published stats are unavailable. Missing counters in a successful summary stay null. |
A SteamID64 identifies the account across these calls. SteamID64 and vanity names explains how to obtain one; name history uses a separate public Steam Community feed.
Private inventory versus an empty inventory
Inventory visibility is per Steam account and game. Request the relevant game instead of assuming that a visible profile exposes every inventory.
curl --fail-with-body --max-time 45 --get \
-H "Authorization: Bearer $WOK_API_KEY" \
--data-urlencode "steam_id=$STEAM_ID" \
--data-urlencode "game=cs2" \
"https://woksteamapi.com/v1/inventory"/v1/inventory returns the normalized result with a status field. Treat private as unavailable and empty as an observed empty inventory. A temporary upstream error is a separate status; use meta.detail for diagnostics and a bounded retry only for transient failures. Show cache age from meta.cache_age when a result came from cache.
Profile visibility can change. WOK may cache a negative private result briefly and invalidates previously public inventory data when a private transition is confirmed. Do not use an old client-side copy as proof that items remain public.
Represent unknown playtime honestly
The example reads only the owned-games endpoint. It sends the key from a server process and keeps visibility=unknown as an explicit state. A zero-hour value is displayed only when Steam actually supplies one.
// Node.js 18+. Keep the WOK key on your server.
const steamId = process.env.STEAM_ID;
const key = process.env.WOK_API_KEY;
const validSteamId = (value) => /^[0-9]{17}$/.test(value ?? "")
&& BigInt(value) > 76561197960265728n
&& BigInt(value) <= 76561202255233023n;
if (!validSteamId(steamId) || !key) {
throw new Error("Set a SteamID64 and WOK_API_KEY");
}
const url = new URL("https://woksteamapi.com/v1/games");
url.searchParams.set("steam_id", steamId);
const response = await fetch(url, {
headers: { Authorization: `Bearer ${key}` },
signal: AbortSignal.timeout(35000),
});
const data = await response.json().catch(() => ({}));
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${JSON.stringify(data.error ?? "non-JSON response")}`);
}
const state = data.visibility === "unknown" ? "not observable" : "visible";
console.log({ state, visibleGames: data.games.length,
totalHours: data.total_playtime_hours });A player can mark an individual game private. Valve says this hides ownership and playtime from other users, so a missing game row cannot prove that the player never owned or played it. See Steam Support: Private Games, ISteamUser profile fields and IPlayerService game fields.
HTTP 400 means the identifier needs correction; 401, 402 and 429 concern WOK authentication or quota. HTTP 502 or 503 indicates a temporary upstream or server-side dependency issue. See the API reference for each endpoint's error contract.
Profile and batch lookupName history and Steam levelInventory status and cacheRust stats privacy