Skip to content

Steam Inventory ​

The Steam Inventory Service holds the items a player owns for your app. It has to be set up in Steamworks first: item definitions live there, not in your game.

Inventory calls do not answer with items. They answer with a result handle, and the items arrive later — either as an inventoryResultReady event carrying that handle, or by asking getResultStatus() until it stops saying 22. A handle you are finished with goes to destroyResult().

A call that Steam cannot answer gives -1 instead of a handle.

Methods ​

loadItemDefinitions() ​

Asks Steam for this app's item definitions. Steam usually has them already; call it once at startup if the inventory looks empty.

getAllItems() ​

Starts reading everything the player owns. Answers a result handle.

javascript
const handle = await steam.getAllItems();

addPromoItem(itemDef) ​

Grants a promo item, if the player is eligible and does not have it already. Answers a result handle.

triggerItemDrop(listDef) ​

Runs a playtime item drop for that item list, if one is due. Answers a result handle.

getResultStatus(handle) ​

Steam's EResult for a handle: 1 done, 22 still pending, 8 nothing matched, 6 Steam could not be asked. Anything else is a failure.

destroyResult(handle) ​

Lets Steam forget a handle.

Examples ​

Reading the inventory, with events ​

The tidy way: start the call, let the event tell you it finished.

javascript
const pending = new Map();

async function loadInventory() {
  const handle = await steam.getAllItems();
  if (handle === -1) return;
  pending.set(handle, 'all-items');
}

// in the loop that drains events
case 'inventoryResultReady':
  if (pending.get(e.handle) === 'all-items') {
    pending.delete(e.handle);
    if (e.result === 1) await showInventory();
    await steam.destroyResult(e.handle);
  }
  break;

Reading it without events ​

javascript
async function waitFor(handle, timeoutMs = 5000) {
  const until = Date.now() + timeoutMs;
  while (Date.now() < until) {
    const status = await steam.getResultStatus(handle);
    if (status !== 22) return status; // 22 is "still pending"
    await new Promise((r) => setTimeout(r, 50));
  }
  return 22;
}

const handle = await steam.getAllItems();
if (handle !== -1) {
  const status = await waitFor(handle);
  if (status === 1) console.log('inventory ready');
  await steam.destroyResult(handle);
}

A playtime drop, once an hour ​

javascript
setInterval(async () => {
  const handle = await steam.triggerItemDrop(MY_DROP_LIST);
  if (handle === -1) return;
  const status = await waitFor(handle);
  if (status === 1) showToast('You found something');
  await steam.destroyResult(handle);
}, 60 * 60 * 1000);

Notes ​

  • Every handle should reach destroyResult(). Steam holds the result until it does.
  • inventoryFullUpdate arrives when the inventory changed for a reason other than a call of yours — a trade, a purchase, a drop on another machine.
  • Without Steam running, every call here answers -1 or 6 and nothing happens, so a game can call them unguarded.