Skip to content

Collectibles

A collectible is a catalog item whose value tracks the real market — graded trading cards, coins, sealed product, action figures. Unlike a normal prize, whose value is frozen at the moment it is won, a collectible is worth whatever it is worth today: the value a player sees in their vault moves, and so does the amount they can cash it back for.

LootBox Solutions keeps those values current for you. Nothing about opening a box changes — a collectibles box is opened, settled and shipped exactly like any other box, on the same endpoints, with the same fairness guarantees.

What actually changes for you

Everything is additive. If you integrate nothing, nothing breaks: normal items keep the payloads they have always had, and an operator without collectibles never sees a collectible field.

SurfaceChange
Box catalog / box detailNew isCollectible flag, plus filter[isCollectible]= so you can split a collectibles grid out of your main one. On detail, collectible prize rows additionally carry isCollectible / collectibleCategory / metadata (and every prize gains imageUrlLarge) so you can offer an item-detail view before the open.
InventoryCollectible rows gain isCollectible, currentRevisionId and wonValueMinor. Their valueMinor is the current value.
Inventory detail / history / portfolioThree new read endpoints for a detail page, a price chart and a portfolio header.
CashoutNew optional expectedRevisionId, and a PRICE_CHANGED refusal when the value moved under the player.
Operator configcapabilities.collectiblesEnabled tells you whether any of this applies.
Opening, fairness, webhooks, the SDKNo change. No new events, no new round or webhook fields.

Availability

Collectibles are enabled per operator, by LootBox Solutions — you cannot turn them on yourself, and the admin surface shows the state read-only. Ask us to enable them for your operator; then read GET /api/s2s/config to know where you stand:

{ "dataVersion": 2, "capabilities": { "collectiblesEnabled": true } }

While the capability is off:

  • collectible boxes are absent from GET /boxes, and filter[isCollectible]=true returns an empty page — not an error;
  • fetching one by id returns UNKNOWN_BOX (404), the same as a box that doesn’t exist — box detail, the version lookup, /launches and /purchase all behave that way, so there is no path to a hidden box;
  • boxes you can’t see can’t be marked collectible on your side either.

Drive your own “collectibles” navigation off the capability flag rather than off an empty catalog page — an empty grid and a disabled feature look identical otherwise.

Owned items always survive. Turning the capability off hides the catalog, never a player’s vault. Collectibles a player already owns stay visible, chartable, cashback-able and shippable through every switch flip, and their values keep tracking. Never gate your inventory surface on the flag.

Where collectible boxes appear

isCollectible is an explicit marker on the box, not something derived from what’s inside it — a mixed box can contain a collectible without being one, so never infer the flag from the prize table.

LootBox Solutions does not decide where those boxes show up on your site; you do. The usual shape is a dedicated collectibles page fed by filter[isCollectible]=true and your main grid fed by filter[isCollectible]=false, so a player browsing sneaker boxes doesn’t land on a graded-card box by accident. Box categories work as normal and are the natural filter within the collectibles page (Pokémon / Magic / coins).

Current value, won value, and cashback

Two numbers travel with every collectible a player owns:

Current value (valueMinor)What the item is worth now. Moves over time.
Won value (wonValueMinor)What it was worth the moment it dropped. Pinned forever.

The difference is the player’s profit or loss — show both, and derive the P/L rather than expecting a field for it. Across a player’s whole collection, use the portfolio aggregate for the header: the item list is paginated, so a total added up from the visible page is not the player’s real total.

Cashback counts the value your operator’s settings pick for a collectible whose price moved: the current value by default, or the won value, chosen separately for a rise and a fall in Catalog → Settings. It then pays the item’s cashback percentage of that value, so cashbackMinor is not the same number as valueMinor in general — show the player cashbackMinor on the buyback button, never the raw current value, and see Cashout for what is left out.

Only settled, published values are ever shown

A player never sees a raw market quote. Values move through review on our side before they are published, and every player-facing figure — the vault list, the detail page, every point on the price chart, the cashback amount — comes from a published value. An item whose latest quote is still being reviewed simply keeps serving its last published value: it is never blocked, never marked “pending” to the player, and cashback is never refused because of it.

The practical consequence for your integration is that these values are stable and quotable. When a player sees an amount, that amount is real until it is republished — and the re-confirm contract tells you exactly when that happened.

When a value moves mid-flow

Because the value can change between the moment you quote it and the moment the player taps confirm, cashback takes an optional expectedRevisionId — the currentRevisionId you showed. If it no longer matches, the call is refused with PRICE_CHANGED (409) carrying the fresh figures, and nothing is settled. Re-prompt with the new amount; if the player agrees, retry with the new id.

This applies in both directions. A value that moved up is refused too: the player agreed to a specific number, and a surprise — pleasant or not — is still a surprise. If you build your own player surface, implement that re-confirm step; there is no server-side “close enough” tolerance.

Sending no expectedRevisionId keeps the old behaviour (settle at whatever the value is when the call lands), which is fine for normal items and for a just-won item, but weak for a collectible sitting in a vault.

Staking in the Upgrader

The Upgrader counts a staked item for exactly what cashing it back would pay in Credits at that moment (an item with no cashback of its own, for its won value) — the same rule as cashback. Once a round settles, the value it was played at is frozen with the round, so later movement never rewrites history.

Stock and backorders

Collectibles are physical goods, so supply is finite. The default behaviour when a collectible in a live box runs out of stock is deliberately quiet:

  • the box keeps selling and the item stays winnable — no sudden disappearance from a prize table a player is looking at, and no change to the odds;
  • a player who wins it and requests shipping gets a normal shipping order; the line is flagged backordered internally so the fulfillment desk knows to restock before shipping it;
  • the box is flagged for review on our side so the situation gets a human decision rather than an automatic one.

On the wire, shipping requests and order statuses are unchanged; a backordered line carries waitingForStock: true in the order payload, so the player can be told the item is waiting for stock. You observe backorders in the Shipments desk of the admin UI, which has a filter for them. Expect the usual “awaiting stock” delay on those orders rather than a distinct status.

Where a box would rather not keep selling an out-of-stock collectible, the alternatives are to drop the item and re-solve the box’s odds at the same price, or to take the box down entirely. Both produce a new published box version (or deactivate the box), which reaches you through the box webhooks you already handle — so keep your catalog cache webhook-driven. Collectible boxes republish more often than static ones.

Building a collectibles surface

A typical Model-B build, on top of what you already have:

  1. Gate on capabilities.collectiblesEnabled.
  2. Split the grid: filter[isCollectible]=true for the collectibles page, false for the main one.
  3. Open boxes exactly as you do today — no new call, no new field.
  4. Split the vault: render isCollectible rows in their own tab, each showing current value and P/L against wonValueMinor, with the portfolio aggregate as the header.
  5. Add a detail page from item detail + price history: step chart, a “won” marker, the attribute table, and buyback / ship actions.
  6. Implement the re-confirm on buyback.

Using the embedded game app instead? Collectible boxes open there, the box page’s prize list opens an item-detail dialog (full name, larger image, and the attributes as a spec table), and the in-iframe Items tab shows the badge, the live current value, and the same re-confirm dialog on buyback. What it deliberately does not have is a collectibles tab or price chart — that richer surface is yours to build with the endpoints above.