# Cheatsheet
Every export, by topic. The guides linked from the introduction explain the background; this page lists signatures, values and fields.
jennifer import "@deckyard/steam/" as steam;
def c as steam .Client init steam .client ("YOUR-KEY" );
Every failure is Error{kind: "steam"}. Each call that takes a Client also throws on a transport failure or a non-JSON reply; the Notes column lists the other conditions. Arguments are checked before any request.
# Which calls need a key
Get a key at https://steamcommunity.com/dev/apikey . Valve rate-limits per key. A key-gated call on a keyless client throws before any request.
Keyless Needs a key newsForApp, newsForAppFeedsplayerSummaries, playerSummary, friendList, playerBans, playerBan, resolveVanityUrl, userGroupscurrentPlayers, globalAchievementRarityownedGames, ownedGameCount, recentlyPlayedGames, steamLevel, badges, badgeProgress, sharedGameLenderappDetails, appDetailsMany, appPrices, packageDetails, featuredplayerAchievements, userStats, gameSchemapriceOverviewappList, appListPagepublishedFileDetails, publishedFile, collectionDetails, collectionItemstradeOffersSummary, tradeOffers, tradeOffer, assetPricesupToDateCheck, serversAtAddress, serverInfo, supportedApiListgameServerAccounts, gameServerInfo, queryLoginTokenresolveAccount with an idresolveAccount with a vanity name
call sends the key when the client has one. The id, URL, money and markup helpers make no request.
# Client
Function Returns Notes client(apiKey)Clientkey trimmed; English, US, USD, 15000 ms timeout, 2 retries, 500 ms backoff; STEAM_VERBOSE = 1, true, yes or on sets verbose clientFromEnv()Clientclient(STEAM_API_KEY), then STEAM_LANGUAGE and STEAM_COUNTRY when not blank; throws when STEAM_COUNTRY is not two letterswithLanguage(c, language)Clientlowercased; throws when blank withCountry(c, countryCode)Clientuppercased; throws unless two letters withCurrency(c, currency)Clienta CURRENCY_* id; throws unless positive withTimeout(c, timeoutMs)Clientidle timeout per read; 0 means http's 30000 ms, not DEFAULT_TIMEOUT_MS; throws when negative withRetries(c, retries)Clientretries of a 429 or 5xx; 0 disables; throws when negative withBackoff(c, backoffMs)Clientfirst retry delay, doubled per attempt, raised to a numeric Retry-After, capped at 30 s; 0 means http's 250 ms, not DEFAULT_BACKOFF_MS; throws when negative setVerbose(c, enabled)Clientprint each request before sending it isVerbose(c)boolhasKey(c)booltrue for a non-empty key call(c, service, method, version, params)json.ValueGET any Web API method; throws when a name is not letter-initial letters and digits, the version is not positive, or the status is not 2xx
Builders return a copy: $c = steam.withCountry($c, "DE");.
Verbose output, one line per request. key, access_token, token and login_token print as <redacted>:
steam> GET https://api.steampowered.com/ISteamUser/GetPlayerSummaries/v2/?steamids=76561197960287930&key=<redacted>
steam> POST https://api.steampowered.com/ISteamRemoteStorage/GetPublishedFileDetails/v1/?itemcount=1&publishedfileids%5B0%5D=450814997
Constant Value Meaning API_BASE"https://api.steampowered.com"Web API host STORE_BASE"https://store.steampowered.com"storefront host COMMUNITY_BASE"https://steamcommunity.com"community host (profiles, market, Workshop) MEDIA_BASE"https://cdn.akamai.steamstatic.com"artwork host DEFAULT_TIMEOUT_MS15000a new client's idle timeout DEFAULT_RETRIES2a new client's retry budget DEFAULT_BACKOFF_MS500a new client's first retry delay MAX_RESPONSE_BYTES33554432body cap (32 MiB) CURRENCY_USD1US dollar, a new client's currency CURRENCY_GBP2pound sterling CURRENCY_EUR3euro CURRENCY_CHF4Swiss franc CURRENCY_RUB5Russian rouble CURRENCY_PLN6Polish zloty CURRENCY_BRL7Brazilian real CURRENCY_JPY8Japanese yen CURRENCY_CAD20Canadian dollar CURRENCY_AUD21Australian dollar
# Client
Field Meaning key as stringWeb API key, "" for keyless use language as stringl / language parameter, e.g. "english"countryCode as stringstorefront country, e.g. "US" currency as intwallet currency id for market prices timeoutMs as intidle timeout in milliseconds retries as intretry budget for a 429 or 5xx backoffMs as intfirst retry delay in milliseconds verbose as boolprint requests
# Steam ids
Every steamId argument in the deck accepts all three notations.
Function Returns Notes parseSteamId(id64)SteamIdthrows when not a 64-bit id toSteamId64(parts)stringignores parts.id64; throws when a field is outside the range Steam issues isSteamId(text)bool17 to 20 digits, universe 1-5, account type at most 10 isSteamId64(text)boola personal account only looksLikeSteamId(text)boolnormalizeSteamId would accept itnormalizeSteamId(text)stringany notation to the id64; throws when none fits toSteamId2(id64)string"STEAM_1:0:11101"; throws for a non-personal accounttoSteamId3(id64)string"[U:1:22202]"; a group is [g:1:W]fromSteamId2(text)stringSTEAM_0 reads as universe 1fromSteamId3(text)stringbrackets optional; honours [U:1:W:instance] accountId(id64)intthe 32-bit account number ("friend id") steamId64FromAccountId(account)stringpersonal account; throws outside 1 to 4294967295 profileUrl(id64)stringhttps://steamcommunity.com/profiles/<id64>; any notationvanityProfileUrl(vanity)stringhttps://steamcommunity.com/id/<name>, name percent-encodedgroupUrl(id64)stringhttps://steamcommunity.com/gid/<id64>accountTypeName(accountType)string"individual", "group", ...; "unknown" outside 0-10
Constant Value Meaning INDIVIDUAL_BASE76561197960265728id64 of personal account number 0 CLAN_BASE103582791429521408id64 of group number 0 UNIVERSE_PUBLIC1the public universe UNIVERSE_MAX5highest universe Steam issues ACCOUNT_INDIVIDUAL1a person ACCOUNT_MULTISEAT2multiseat (cyber-cafe) account ACCOUNT_GAME_SERVER3persistent game server ACCOUNT_ANON_GAME_SERVER4anonymous game server ACCOUNT_CONTENT_SERVER6content server ACCOUNT_CLAN7group ACCOUNT_CHAT8chat room ACCOUNT_ANON_USER10anonymous user
# SteamId
Field Meaning id64 as string17-digit decimal id universe as intbits 56-63; 1 = public accountType as intbits 52-55; 1 = individual, 7 = group instance as intbits 32-51; 1 for a desktop account accountId as intbits 0-31, the "friend id"
jennifer steam .toSteamId2 ("76561197960287930" );
steam .fromSteamId3 ("[g:1:4]" );
steam .accountTypeName (steam .parseSteamId ("103582791429521412" ).accountType);
# Users (ISteamUser)
Function Returns Notes playerSummaries(c, steamIds)list of PlayerSummary1 to 100 ids; unknown accounts are left out playerSummary(c, steamId)PlayerSummarythrows when the account is unknown friendList(c, steamId)list of Friendoldest first; empty when private playerBans(c, steamIds)list of PlayerBan1 to 100 ids playerBan(c, steamId)PlayerBanthrows when there is no record resolveVanityUrl(c, vanity)stringid64, "" when no profile has the name resolveAccount(c, text)stringid in any notation, vanity name or /id/<name> URL; only a vanity name costs a request; throws when nothing matches userGroups(c, steamId)list of stringgroup id64s; empty when private personaStateName(state)string"offline", "online", "busy", ...; "unknown" otherwise visibilityName(visibility)string"private", "friends only", "public"; "unknown" otherwise isPublic(player)boolcommunityVisibilityState is VISIBILITY_PUBLICisOnline(player)boolany state but offline isInGame(player)boolgameId is neither "" nor "0"
Constant Value Meaning PERSONA_OFFLINE0signed out PERSONA_ONLINE1signed in PERSONA_BUSY2busy PERSONA_AWAY3away PERSONA_SNOOZE4idle long enough to snooze PERSONA_LOOKING_TO_TRADE5looking to trade PERSONA_LOOKING_TO_PLAY6looking to play VISIBILITY_PRIVATE1only the account itself VISIBILITY_FRIENDS2friends VISIBILITY_PUBLIC3everyone RELATIONSHIP_FRIEND"friend"the friend-list relationship SUMMARY_BATCH100largest playerSummaries / playerBans batch
# PlayerSummary
Only steamId, personaName, profileUrl, the avatars and personaState are guaranteed. The rest is filled in only for a public profile that publishes the field, so "" or 0 means "not shared".
Field Meaning steamId as stringid64 personaName as stringdisplay name profileUrl as stringcommunity profile URL avatar as string32x32 avatar URL avatarMedium as string64x64 avatar URL avatarFull as string184x184 avatar URL avatarHash as stringhash shared by the avatar URLs personaState as inta PERSONA_* value communityVisibilityState as inta VISIBILITY_* value profileState as int1 once a community profile is configured lastLogoff as intUnix time of the last sign-out commentPermission as intnon-zero when strangers may comment realName as stringreal name primaryClanId as stringid64 of the primary group timeCreated as intUnix time the account was created personaStateFlags as intclient flags countryCode as stringtwo-letter country stateCode as stringregion within the country cityId as intSteam's city id gameId as stringapp being played, "" or "0" when none gameExtraInfo as stringtitle being played gameServerIp as stringserver being played on
# Friend
Field Meaning steamId as stringthe friend's id64 relationship as string"friend" friendSince as intUnix time of the friendship
# PlayerBan
Field Meaning steamId as stringid64 communityBanned as boolbanned from community features vacBanned as boolat least one VAC ban vacBans as intVAC bans across all games gameBans as intdeveloper-issued game bans daysSinceLastBan as int0 when never banned economyBan as string"none", "probation" or "banned"
# Player (IPlayerService)
These need the account's game details to be public; a private library comes back empty, not as an error.
Function Returns Notes ownedGames(c, steamId, includeAppInfo, includeFreeGames)list of OwnedGameincludeAppInfo adds name and icon; without includeFreeGames played free-to-play titles are left outownedGameCount(c, steamId)intcounts played free-to-play titles; 0 when private recentlyPlayedGames(c, steamId, count)list of OwnedGamelast two weeks, most recent first; throws unless count is positive steamLevel(c, steamId)int0 when hidden badges(c, steamId)BadgeCollectionbadgeProgress(c, steamId, badgeId)list of BadgeQuestthrows unless badgeId is positive sharedGameLender(c, steamId, appId)stringthe Family Sharing lender's id64, "" when owned playtimeHours(minutes)floathours, rounded to one decimal totalPlaytime(games)intsum of playtimeForever, minutes mostPlayed(games, count)list of OwnedGamelongest playtimeForever first; throws unless count is positive unplayed(games)list of OwnedGamezero playtimeForever gameIconUrl(appId, iconHash)string"" for an empty hash
# OwnedGame
Field Meaning appId as intapp id name as stringtitle, "" without app info playtimeForever as intlifetime minutes playtimeTwoWeeks as intminutes in the last two weeks playtimeWindows as intlifetime minutes on Windows playtimeMac as intlifetime minutes on macOS playtimeLinux as intlifetime minutes on Linux playtimeDeck as intlifetime minutes on a Steam Deck iconHash as stringicon hash for gameIconUrl, "" without app info hasCommunityVisibleStats as boolthe game publishes stats lastPlayed as intUnix time of the last launch, 0 when never
# Badge
Field Meaning badgeId as intbadge id appId as intapp, 0 for a Steam-wide badge level as intbadge level completionTime as intUnix time the level was reached xp as intexperience it is worth scarcity as intaccounts holding it communityItemId as stringcommunity item id borderColor as int1 for a foil badge
# BadgeCollection
Field Meaning playerLevel as intSteam level playerXp as inttotal experience xpNeededToLevelUp as intexperience missing for the next level xpNeededCurrentLevel as intexperience the current level started at badges as list of Badgeevery badge held
# BadgeQuest
Field Meaning questId as inttask id completed as booldone
# Stats (ISteamUserStats)
Function Returns Notes playerAchievements(c, steamId, appId)PlayerAchievementslocalized; throws when Steam refuses (private profile, unowned game, no stats) userStats(c, steamId, appId)list of StatValueempty when the game keeps none globalAchievementRarity(c, appId)list of AchievementRaritykeyless; internal names currentPlayers(c, appId)intkeyless; throws when Steam has no count gameSchema(c, appId)GameSchemalocalized unlockedCount(achievements)intcompletionPercent(achievements)float0.0 to 100.0; 0.0 for none lockedAchievements(achievements)list of Achievementnot yet earned rarest(rarities, count)list of AchievementRaritylowest percentage first; throws unless count is positive
# Achievement
Field Meaning apiName as stringinternal name achieved as boolunlocked unlockTime as intUnix time, 0 while locked name as stringdisplay name description as string"" while a hidden achievement is locked
# PlayerAchievements
Field Meaning steamId as stringaccount appId as intgame gameName as stringtitle achievements as list of Achievementevery achievement, locked or not
# StatValue
Field Meaning name as stringinternal name value as intcurrent value
# AchievementRarity
Field Meaning name as stringinternal name, to join with SchemaAchievement.name percent as floatshare of players, 0-100
# SchemaAchievement
Field Meaning name as stringinternal name displayName as stringlocalized title description as stringlocalized description, "" when hidden hidden as booldescription withheld until unlocked icon as stringunlocked icon URL iconGray as stringlocked icon URL
# SchemaStat
Field Meaning name as stringinternal name displayName as stringlocalized label, "" when none defaultValue as intstarting value
# GameSchema
Field Meaning appId as intgame gameName as stringtitle gameVersion as stringschema version achievements as list of SchemaAchievementdefined achievements stats as list of SchemaStatdefined statistics
# Apps (IStoreService, ISteamApps, ISteamWebAPIUtil)
Function Returns Notes appListPage(c, lastAppId, maxResults)AppListPagegames only; lastAppId 0 to start; maxResults 1 to 50000 appList(c, maxPages)list of Apppages of 50000 until none are left or maxPages is reached findApps(apps, term)list of Appcase-insensitive substring; throws on a blank term appById(apps, appId)AppappId 0 and name "" when absentupToDateCheck(c, appId, version)VersionCheckkeyless; throws on a negative version serversAtAddress(c, address)list of GameServerkeyless; ip or ip:port; empty when none serverInfo(c)ServerInfokeyless supportedApiList(c)list of ApiMethodthe public methods, plus those the key unlocks storePageUrl(appId)stringhttps://store.steampowered.com/app/<id>headerImageUrl(appId)string<MEDIA_BASE>/steam/apps/<id>/header.jpgcapsuleImageUrl(appId)string<MEDIA_BASE>/steam/apps/<id>/capsule_231x87.jpg
Constant Value Meaning APPLIST_PAGE_MAX50000largest catalogue page
# App
Field Meaning appId as intapp id name as stringname
# AppListPage
Field Meaning apps as list of Appthe entries lastAppId as intpass as lastAppId for the next page haveMore as boolanother page follows
# VersionCheck
Field Meaning upToDate as boolthe version is current versionIsListable as boolSteam still lists it requiredVersion as intlowest version allowed to connect message as stringSteam's explanation, "" when none
# GameServer
Field Meaning address as stringip:portappId as intgame gameDir as stringgame directory, e.g. "tf" region as intSteam region code gamePort as intclient port specPort as intSourceTV port, 0 when none secure as boolVAC enabled lan as boolLAN-only
# ServerInfo
Field Meaning serverTime as intUnix time at Steam serverTimeString as stringthe same, formatted by Steam
# ApiMethod
Field Meaning interfaceName as stringe.g. "ISteamUser" name as stringe.g. "GetPlayerSummaries" version as intmethod version httpMethod as string"GET" or "POST" parameters as list of stringparameter names
# News (ISteamNews)
Function Returns Notes newsForApp(c, appId, count, maxLength)list of NewsItemnewest first; maxLength 0 for whole bodies; throws unless count is positive or when maxLength is negative newsForAppFeeds(c, appId, count, maxLength, feeds)list of NewsItemas newsForApp, from comma-separated feeds ("" for all) plainText(markup)stringstrips HTML and BBCode, see news summarize(text, maxChars)stringat most maxChars characters, cut at a word, ending in one …; throws unless maxChars is positive
Constant Value Meaning FEED_ANNOUNCEMENTS"steam_community_announcements"the game's own announcements FEED_STEAM"steam_updates"Steam's editorial posts MARKUP_SPAN512longest run, in code points, plainText reads as one tag BLOCK_TAGSbr, p, div, li, ul, ol, tr, td, th, table, blockquote, h1-h6, hr, pre, list, olist, quote, code, * tags plainText replaces with a space BBCODE_TAGSb, i, u, s, strike, url, img, list, olist, *, quote, code, noparse, h1-h3, hr, spoiler, table, tr, th, td, previewyoutube, dynamiclink, carousel, expand, video, steamwidget, randomboxes BBCode tags plainText removes CLAN_IMAGE_TOKENS{STEAM_CLAN_LOC_IMAGE}, {STEAM_CLAN_IMAGE}image embeds plainText drops with their path
# NewsItem
Field Meaning gid as stringunique id title as stringheadline url as stringwhere to read it isExternalUrl as boolurl leaves Steamauthor as stringposter, "" when none contents as stringbody, HTML and/or BBCode feedLabel as stringfeed label, e.g. "Community Announcements" feedName as stringfeed name for feeds, e.g. "steam_community_announcements" feedType as intSteam's feed type date as intUnix time posted appId as intgame
# Store (store.steampowered.com)
Keyless and regional: the client's countryCode and language go with every request. One request per app id.
Function Returns Notes appDetails(c, appId)AppDetailsthrows when there is no record (delisted, region-locked, not an app) appDetailsMany(c, appIds)list of AppDetailsids without a record are left out appPrices(c, appIds)list of AppPriceone entry per id, found false without a record; throws on an empty list packageDetails(c, packageId)PackageDetailsthrows unless positive, or when there is no record featured(c)FeaturedListsisDiscounted(price)booldiscountPercent > 0 and final < initialsavings(price)intinitial - final in minor units, 0 when not discountedmajorUnits(minorUnits)floatdivided by 100, yen included discountLabel(price)stringe.g. "-66%", "" when not discounted
The id lists are checked in full before the first request; a transport failure throws rather than shortening the list.
Constant Value Meaning APPDETAILS_PATH"/api/appdetails"app record path PACKAGEDETAILS_PATH"/api/packagedetails"package record path FEATURED_PATH"/api/featured"featured lists path
# Price
Amounts are ints in minor units. A free or unreleased title has a zeroed Price.
Field Meaning currency as stringISO code, e.g. "EUR" initial as intundiscounted price final as intcurrent price discountPercent as int0 when none initialFormatted as stringSteam's rendering of initial, "" at full price finalFormatted as stringSteam's rendering of final, the one to show
Field Meaning windows as boolWindows build mac as boolmacOS build linux as boolnative Linux build (Proton not counted)
# AppDetails
Field Meaning appId as intapp id name as stringtitle kind as string"game", "dlc", "demo", "music", ... requiredAge as intage gate, 0 when none isFree as boolcosts nothing shortDescription as stringblurb, HTML aboutTheGame as stringlong description, HTML supportedLanguages as stringlanguage list, HTML headerImage as stringbanner URL capsuleImage as stringcapsule URL website as stringdeveloper site, "" when none developers as list of stringdevelopers publishers as list of stringpublishers price as Pricezeroed when free or unreleased platforms as Platformsbuilds categories as list of stringe.g. "Multi-player" genres as list of stringe.g. "Action" dlc as list of intDLC app ids metacriticScore as int0 when unscored metacriticUrl as string"" when unscored recommendations as intuser recommendations achievementCount as intachievements defined releaseDate as stringas Steam renders it comingSoon as boolnot yet released
# AppPrice
Field Meaning appId as intapp id found as boolthe storefront had a record free as boolfree to play price as Pricezeroed when free or not found
# PackageDetails
Field Meaning packageId as intpackage id name as stringname pageImage as stringstore image URL apps as list of Appapps in it price as Priceprice platforms as Platformsbuilds releaseDate as stringas Steam renders it comingSoon as boolnot yet released
# FeaturedApp
Field Meaning appId as intapp id name as stringtitle discounted as boolon sale discountPercent as int0 when none originalPrice as intundiscounted, minor units finalPrice as intcurrent, minor units currency as stringISO code capsuleImage as stringwide capsule URL headerImage as stringheader URL windowsAvailable as boolWindows build macAvailable as boolmacOS build linuxAvailable as boolnative Linux build
# FeaturedLists
Field Meaning largeCapsules as list of FeaturedAppfront-page banners, often empty outside a sale windows as list of FeaturedAppfeatured for Windows mac as list of FeaturedAppfeatured for macOS linux as list of FeaturedAppfeatured for Linux
Function Returns Notes priceOverview(c, appId, marketHashName)MarketPricekeyless; in the client's currency; found false when unpriced; roughly 20 requests a minute per address marketListingUrl(appId, marketHashName)stringname percent-encoded marketSearchUrl(appId, term)stringterm "" browses everythingcurrencyCode(currency)stringISO code of a CURRENCY_* id, "" for any other parseMoney(text)floatlast . or , is decimal when 1 or 2 digits follow; 0.0 when unreadable parseMoneyCents(text)intparseMoney x 100, rounded; 0 past MAX_MONEY_UNITSparseCount(text)intdigits only; 0 when none or too large
Constant Value Meaning PRICEOVERVIEW_PATH"/market/priceoverview/"price path MAX_MONEY_UNITS1.0e15largest amount parseMoneyCents scales
# MarketPrice
Field Meaning found as boolthe market had a price lowestPrice as stringcheapest listing, as Steam formatted it medianPrice as stringmedian recent sale, as Steam formatted it lowestCents as intlowestPrice in minor unitsmedianCents as intmedianPrice in minor unitsvolume as intsold in the last 24 hours, 0 when Steam omits it
# Workshop (ISteamRemoteStorage)
Keyless. Both lookups are form POSTs with indexed publishedfileids[N] fields; Steam answers nothing else here.
Function Returns Notes publishedFileDetails(c, publishedFileIds)list of PublishedFile1 to 100 numeric ids; unknown items left out publishedFile(c, publishedFileId)PublishedFilethrows when there is no such item collectionDetails(c, collectionIds)list of Collection1 to 100 numeric ids; one entry per id, in order collectionItems(c, collectionId)list of stringmember ids in collection order; throws when there is no such collection workshopUrl(publishedFileId)stringhttps://steamcommunity.com/sharedfiles/filedetails/?id=<id>workshopBrowseUrl(appId)stringhttps://store.steampowered.com/app/<id>/workshop/workshopVisibilityName(visibility)string"public", "friends only", "private", "unlisted"; "unknown" otherwise
Constant Value Meaning WORKSHOP_PUBLIC0anyone WORKSHOP_FRIENDS1the author's friends WORKSHOP_PRIVATE2the author WORKSHOP_UNLISTED3by direct link, not listed WORKSHOP_BATCH100largest batch per request
# PublishedFile
Field Meaning publishedFileId as stringid, the number in the Workshop URL creator as stringauthor's id64 creatorAppId as intapp it was authored in consumerAppId as intapp it is played in title as stringtitle description as stringBBCode filename as stringstored file name fileSize as intbytes fileUrl as stringdirect download, "" for most items previewUrl as stringpreview image URL timeCreated as intUnix time published timeUpdated as intUnix time updated visibility as inta WORKSHOP_* value banned as boolbanned by Valve banReason as string"" when not banned subscriptions as intcurrent subscribers favorited as intcurrent favourites lifetimeSubscriptions as intsubscribers ever lifetimeFavorited as intfavourites ever views as intpage views tags as list of stringWorkshop tags
# CollectionItem
Field Meaning publishedFileId as stringmember id sortOrder as intposition fileType as intSteam's file-type code
# Collection
Field Meaning publishedFileId as stringthe collection's id found as boolSteam had it items as list of CollectionItemmembers in order
# Econ (IEconService, ISteamEconomy)
The trade calls read the key owner's own offers; there is no steamid parameter. Accepting and declining are not offered: they need the mobile confirmation flow.
Function Returns Notes tradeOffersSummary(c, timeCutoff)TradeOffersSummarycounts only; timeCutoff 0 counts everything; throws when negative tradeOffers(c, getSent, getReceived, activeOnly)TradeOffersthrows when both directions are false tradeOffer(c, tradeOfferId)TradeOfferthrows on a non-numeric id or an offer the key cannot see assetPrices(c, appId)list of AssetPricethrows when the game has no item store tradeOfferStateName(state)stringstates 1-11, "unknown" otherwise isPendingOffer(offer)boolactive (2) or awaiting confirmation (9) isOneSided(offer)boolone side is empty
Constant Value Meaning TRADE_ACTIVE2waiting for the other side TRADE_ACCEPTED3items exchanged TRADE_CANCELED6withdrawn by the sender TRADE_DECLINED7turned down by the recipient TRADE_IN_ESCROW11accepted, items in escrow
# TradeAsset
Field Meaning appId as intgame contextId as stringinventory context assetId as stringinventory id classId as stringitem class instanceId as stringitem instance amount as intcount, for a stackable item missing as boolleft the inventory since the offer; accepting fails
# TradeOffer
Field Meaning tradeOfferId as stringid otherSteamId as stringother party's id64, widened from the 32-bit id Steam sends message as stringnote state as inta TRADE_* value or another state 1-11 isOurOffer as boolthe key's account made it timeCreated as intUnix time made timeUpdated as intUnix time last changed expirationTime as intUnix time it lapses escrowEndDate as intUnix time escrow lifts, 0 when none toGive as list of TradeAssetwhat the key's account hands over toReceive as list of TradeAssetwhat it gets
# TradeOffers
Field Meaning sent as list of TradeOffermade by the account received as list of TradeOffermade to the account
Field Meaning pendingReceived as intincoming, awaiting an answer newReceived as intincoming since the cutoff updatedReceived as intincoming changed since the cutoff pendingSent as intoutgoing, awaiting an answer newlyAcceptedSent as intoutgoing accepted since the cutoff updatedSent as intoutgoing changed since the cutoff escrowReceived as intincoming in escrow escrowSent as intoutgoing in escrow
# AssetPrice
Field Meaning classId as stringitem class name as stringthe store's internal name date as stringdate added, "" when none prices as map of string to intminor units per ISO code; only the codes Valve priced
Function Returns Notes gameServerAccounts(c)list of GameServerAccountthe key owner's accounts, login tokens included gameServerInfo(c, steamId)GameServerInfopublic record of any server account queryLoginToken(c, loginToken)LoginTokenStatusthrows on a blank token isUsableServerAccount(account)boolneither deleted nor expired
# GameServerAccount
Field Meaning steamId as stringserver's id64 appId as intgame loginToken as stringsecret, treat as a password memo as stringnote deleted as booldeleted expired as booltoken expired through disuse lastLogon as intUnix time of the last login
# GameServerInfo
Field Meaning steamId as stringserver's id64 appId as intgame, 0 when unknown
# LoginTokenStatus
Field Meaning steamId as stringowning server account banned as boolbanned from listing expires as intUnix time it stops working, 0 when it does not
# Errors
Messages name the fix or the cause:
validation: the app id must be positive, got 0 transport: GET https://store.steampowered.com/api/appdetails failed: ... (the URL never carries the query string, so never the key) refusal: the storefront has no record of app 1 in country US - it may be delisted, region-locked, or not an app at all
A non-2xx GET reads ... failed: rest.getJson: HTTP <status>: <body>. A non-2xx POST names the usual cause: 400 rejected parameters, 401 missing or invalid key, 403 key not allowed to read the profile, 404 no such method or object, 429 rate limited, 500/502/503 Steam trouble.
jennifer try {
def d as steam .AppDetails init steam .appDetails ($c , $appId );
} catch (e) {
io .eprintf ("%s\n" , $e .message);
}
# Costs
One connection per request. rest keeps no keep-alive session, so appPrices, appDetailsMany and appList pay a TLS handshake per id or page.Bodies are capped at MAX_RESPONSE_BYTES (32 MiB).plainText is linear in the body length , also on adversarial input (loose brackets, repeated image markers), so it is safe on user-written Workshop descriptions.
# Requirements
Jennifer 0.25.0 or newer, the default jennifer binary: requests go through rest and http to net, which jennifer-tiny stubs out. The pure helpers work on both. Standard library strings, lists, convert, math, json, io, os; bundled modules rest, http, uri. No other deck.
Tests run offline: jennifer test src/steam_test.j. Anchor a filter to ^test (--filter='^testParseMoney'); the refusal helpers are top-level functions that throw by design.