Skip to content

Inventory

Joël Deffner edited this page Sep 4, 2026 · 1 revision

Inventory

Since v0.6.0. steam.items is the curated layer over ISteamInventory: read and change the player's Steam Inventory Service items, the item definition catalogue, and store prices.

Nearly every raw ISteamInventory call writes a SteamInventoryResult_t handle, finishes later with a SteamInventoryResultReady_t callback, and has to be destroyed or it leaks. Every method here runs that whole cycle: start the call, wait for the result, decode the items, destroy the handle. A non-OK EResult becomes a SteamResultError. See Errors.

Item definitions are the catalogue you configure on the partner site, a separate thing from items: they arrive with loadDefinitions, and everything reading them is synchronous afterwards. The instance is cached lazily on the Steam object, and is called items because the generated accessor owns steam.inventory, where the unwrapped calls live.

getAll

getAll(): Promise<InventoryItem[]>

Every item stack the player owns for this app. Empty for a player who owns nothing.

getByIds

getByIds(itemIds: bigint[]): Promise<InventoryItem[]>

The named stacks only, cheaper than getAll when you know the ids. Ids the player does not own are left out; an empty input skips the native call.

loadDefinitions

loadDefinitions(): Promise<void>

Downloads the item definition catalogue and resolves once Steam has it. Call it once at startup: listDefinitions, definitionProperty and definitionProperties read the cache it fills, and return nothing before it is filled.

listDefinitions

listDefinitions(): number[]

The definition ids in the loaded catalogue, or an empty array while the catalogue is not loaded.

definitionProperty

definitionProperty(definition: number, name: string): string | null

One property of one definition, or null when the definition or the property does not exist. Every property is a string whatever its type on the partner site: a boolean is "true", a number its digits. An empty name returns the definition's comma-separated list of property names.

definitionProperties

definitionProperties(definition: number): Record<string, string>

Every property of one definition, as one object: one flat call for the key list, then one per key. Empty when the definition does not exist or the catalogue is not loaded. Null prototype, so a __proto__ key stays an entry.

consume

consume(itemId: bigint, quantity?: number): Promise<InventoryItem[]>

Consumes some of one stack, permanently: the "use the potion" call. quantity defaults to 1. Resolves with the stack afterwards, empty once the last is gone.

exchange

exchange(generate: { definition: number; quantity: number }[], destroy: { itemId: bigint; quantity: number }[]): Promise<InventoryItem[]>

Crafts items out of other items in one step. Steam checks it against the recipes on the partner site and refuses anything else, so this cannot mint items on its own.

transfer

transfer(sourceItemId: bigint, quantity: number, destinationItemId?: bigint): Promise<InventoryItem[]>

Moves quantity between two stacks. With no destination (the default, k_SteamItemInstanceIDInvalid) it moves into a brand new stack, which is how you split one. With a destination the two stacks merge, which only works when both are of the same definition.

generate

generate(items: { definition: number; quantity: number }[]): Promise<InventoryItem[]>

Creates items out of nothing, to seed a test inventory. Developer accounts only: it fails with k_EResultAccessDenied in a shipped build.

grantPromoItems

grantPromoItems(): Promise<InventoryItem[]>

Grants every promo item this player is eligible for, by the promo rules on the partner site. Granting one they already have is a no-op, so calling this at startup is safe. Empty when there was nothing to grant.

addPromoItems

addPromoItems(definitions: number[]): Promise<InventoryItem[]>

The narrow form of grantPromoItems: grants only the named definitions, and only if the player is eligible for them.

triggerDrop

triggerDrop(dropListDefinition: number): Promise<InventoryItem[]>

Asks Steam whether a timed drop is due, and takes it if it is. Steam decides, so most calls come back with no items and that is not an error. Do not poll it; call it at the end of a match.

sendDropHeartbeat

sendDropHeartbeat(): void

Tells Steam the player is still playing, for playtime-based drops. Send it about once a minute. Steam gives no result, so it cannot fail.

requestPrices

requestPrices(): Promise<string>

Downloads the current prices and resolves with their three-letter currency code, for example EUR. listPrices and price read the cache it fills, so call this first. Only definitions on sale have a price.

listPrices

listPrices(): ItemPrice[]

Every definition that has a price, empty before requestPrices resolved. Prices are in the smallest currency unit, so 199 means 1.99 with cents.

price

price(definition: number): { currentPrice: bigint; basePrice: bigint } | null

The price of one definition, or null when it is not for sale.

startPurchase

startPurchase(items: { definition: number; quantity: number }[]): Promise<{ orderId: bigint; transactionId: bigint }>

Starts a purchase and resolves once Steam accepted the order. The checkout appears in the overlay, so the overlay has to be enabled. Resolving means the order exists, not that the player paid: the items arrive later, which onChange hears about.

onChange

onChange(listener: (items: InventoryItem[]) => void): () => void

Subscribes to Steam's own SteamInventoryFullUpdate_t, which fires whenever the inventory changed outside this process: a purchase, a trade, a market sale. The listener gets the full item list, already decoded, and the result handle is destroyed afterwards. Returns an unsubscribe function.

Types

InventoryItem

One item stack, decoded from SteamItemDetails_t.

Field Type Meaning
itemId bigint SteamItemInstanceID_t, unique per stack. 64-bit, so a bigint.
definition number SteamItemDef_t: which item definition this stack is of.
quantity number How many of the item the stack holds.
flags number ESteamItemFlags bits: 1 no trade, 256 removed, 512 consumed.

ItemPrice

One entry from listPrices.

Field Type Meaning
definition number SteamItemDef_t the price belongs to.
currentPrice bigint Price the user pays now, in the smallest currency unit.
basePrice bigint Price before any discount, in the smallest currency unit.

Errors

Shape When
SteamResultError The result completed with a non-OK EResult. Common values: k_EResultAccessDenied (generate on a non-developer account), k_EResultInvalidParam (an item the player does not own, or a definition that is not for sale), k_EResultInvalidState (no Inventory Service configured).
Error: steamwand: <call> returned false (invalid handle or argument?) The flat call refused to start, which usually means the app has no Inventory Service. Also GetResultItems on a handle Steam already dropped.
SteamApiCallError requestPrices or startPurchase never produced a usable result. See How It Works.

What this layer does not do

The rest of ISteamInventory is on the raw generated steam.inventory:

  • TradeItems, the peer to peer trade, and InspectItem, which reads an item from an inspection token.
  • SerializeResult and DeserializeResult, which move a result across the wire so a game server can verify what a client claims to own.
  • StartUpdateProperties, the SetProperty* family, RemoveProperty and SubmitUpdateProperties, which write per-item dynamic properties.
  • RequestEligiblePromoItemDefinitionsIDs and GetEligiblePromoItemDefinitionIDs, which ask what a user could be granted.
  • GetResultStatus, GetResultTimestamp, CheckResultSteamID and GetResultItemProperty, plus DestroyResult, handled for you here.

Those take raw Buffer out params and return flat booleans or call handles. Flat API explains the calling convention.

Clone this wiki locally