Amba

Inventory

User inventory, atomic virtual-currency purchases, consumable consumption.

All mutations run inside a transaction with SELECT ... FOR UPDATE on user_balances so concurrent purchases cannot double-spend.

Source: apps/api/src/routes/client/inventory.ts.

Endpoints

MethodPathDescription
GET/client/inventoryUser's inventory with catalog-item info; quantity > 0.
POST/client/inventory/purchasePurchase with virtual currency (atomic, idempotent per concurrency).
POST/client/inventory/:itemId/consumeDecrement quantity on a consumable.

GET /client/inventory

Response 200

{
  "data": [
    {
      "app_user_id": "…",
      "catalog_item_id": "…",
      "quantity": 3,
      "acquired_via": "store_purchase",
      "acquired_at": "…",
      "catalog_items": {
        "key": "…",
        "name": "…",
        "icon_url": "…",
        "item_type": "consumable",
        "category": "…"
      }
    }
  ]
}

Errors

  • 500 FETCH_FAILED.

Try it:

GET/client/inventory
client auth
curl -X GET 'https://api.amba.dev/client/inventory'
Loading auth… Configure auth in the settings drawer (top-right) to run this request.

Curl:

curl -X GET '${BASE_URL}/client/inventory' \
  -H 'X-Api-Key: ${CLIENT_API_KEY}' \
  -H 'Authorization: Bearer ${SESSION_TOKEN}'

POST /client/inventory/purchase

Atomic: price resolution → balance check → deduction → ledger insert → inventory grant. Bundles are expanded — each bundle content item is granted separately.

Request (PurchaseItemInput)

FieldTypeRequiredDescription
catalog_item_iduuidyesItem to buy.
currency_codestringyesCurrency to spend.
store_iduuidnoIf present, the store's override_prices and max_purchases_per_user are applied.

Response 200

{ "data": { "purchased": true, "currency_code": "gems", "price": 100, "balance_after": 900 } }

Errors

  • 400 NO_PRICE — no price set for the (item, currency) pair.
  • 400 MAX_PURCHASES_REACHED — store listing's per-user cap reached.
  • 400 INSUFFICIENT_BALANCE — user's currency balance is less than the price.
  • 404 NOT_FOUND — item not listed in the supplied store_id.
  • 503 TENANT_UNAVAILABLE — tenant DB unavailable.
  • 500 PURCHASE_FAILED.

Try it:

POST/client/inventory/purchase
client auth
curl -X POST 'https://api.amba.dev/client/inventory/purchase'
Loading auth… Configure auth in the settings drawer (top-right) to run this request.

Curl:

curl -X POST '${BASE_URL}/client/inventory/purchase' \
  -H 'X-Api-Key: ${CLIENT_API_KEY}' \
  -H 'Authorization: Bearer ${SESSION_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{}'

POST /client/inventory/:itemId/consume

Decrement quantity on a consumable. itemId is the catalog item id.

Request

{ "quantity": 1 }

Defaults to quantity = 1 if body is empty or missing the field.

Response 200

{ "data": { "app_user_id": "…", "catalog_item_id": "…", "quantity": 2 } }

Errors

  • 400 NOT_CONSUMABLE — the catalog item is not item_type = 'consumable'.
  • 400 INSUFFICIENT_QUANTITY — user doesn't own enough to consume.
  • 500 CONSUME_FAILED.

Try it:

POST/client/inventory/%7B%7BitemId%7D%7D/consume
client auth
curl -X POST 'https://api.amba.dev/client/inventory/%7B%7BitemId%7D%7D/consume' \
  -H 'Content-Type: application/json' \
  -d '{
  "quantity": 1
}'
Loading auth… Configure auth in the settings drawer (top-right) to run this request.

Curl:

curl -X POST '${BASE_URL}/client/inventory/{itemId}/consume' \
  -H 'X-Api-Key: ${CLIENT_API_KEY}' \
  -H 'Authorization: Bearer ${SESSION_TOKEN}' \
  -H 'Content-Type: application/json' \
  -d '{"quantity":1}'

On this page