KUMODeck

Inventory

Currencies (credits, coins, gems) and items (unlocks, skins, potions) are owned per user (called players in the API). The rule that keeps balances honest: the client can read and spend, but never create. Balances grow only on the server, through rewarded ads.

You do not have to use it. If you run your own payments (your own Stripe, for example) or keep balances in your own Functions and database, skip this page. It is off until you turn it on:

kumo.config.json
{ "features": { "inventory": true } }

Then push it with kumodeck config push.

For games: the examples below use a game's coins, gems and items. An app's credits work the same way.

Declare#

{
  "currencies": [
    { "key": "coins", "title": "Coins", "initial": 100, "max": 1000000 },
    { "key": "gems" }
  ],
  "items": [
    { "key": "potion", "kind": "consumable", "max": 99 },
    { "key": "red_skin", "kind": "durable", "title": "Red Skin" }
  ]
}
kindMeaningDefault cap
consumableused up when spent (potions, tickets)1e9
durableowned or not (skins, unlocks) — cannot be spent1
collectiblelike durable, grouped separately for collection UIs1

Currencies start at initial (granted on the user's first inventory read) and are capped at max. Grants that would exceed a cap are clamped; the response tells you what was actually added.

Read and spend#

// { currencies: { coins: 100 }, items: { potion: 2 } }
const inv = await kumo.inventory.get();

await kumo.inventory.consume({ items: { potion: 1 } });

consume is all or nothing: if anything is short, nothing changes and you get 409 insufficient with details.shortages. The SDK attaches an Idempotency-Key automatically, so a retried request never spends twice. Durable and collectible items cannot be consumed.

Spending coins on something in your game (a continue, a hint) is consume followed by your own game logic:

try {
  await kumo.inventory.consume({ currencies: { coins: 50 } });
  continueRun();
} catch (e) {
  // e.g. watch an ad for more coins
  if (e.code === 'insufficient') offerRewardedAd();
  else throw e;
}

A user sees and spends only their own inventory: your publishable key and the user's login allow nothing else. After a rewarded ad, read it again with kumo.inventory.get() — the ads guide shows where.

Every change — ad reward, spend — is recorded in a ledger with the balance after it.