Box detail
GET /api/s2s/boxes/{boxId} returns the full detail for a single box — its
price plus the complete prize table (each prize’s value, image, and drop
odds) and the fairness snapshot link. Use it when you
drive the open from your backend
and render the box page, reel, and “show odds” list yourself.
The catalog (GET /api/s2s/boxes) lists box-level
cards (name, price, image); this endpoint adds the per-box prize detail those
cards don’t carry. Fetch it when a player opens a box page, then
POST /purchase to open.
Request
GET https://{operator}.app.lootboxsolutions.com/api/s2s/boxes/42GET https://{operator}.app.lootboxsolutions.com/api/s2s/boxes/42?currency=EUR&locale=pt-BR| Query | Notes |
|---|---|
currency | ISO-4217 code. The box price and every prize value come back in this currency; must be one of your configured currencies. Defaults to the operator default. |
locale | BCP-47-ish code (e.g. en, pt-BR). Localizes the box and prize names where a translation exists, falling back to the best-available copy. Defaults to the operator default. |
Response
{ "box": { "boxId": 42, "boxVersionId": 1201, "name": "Dragon Box", "priceMinor": 500, "currency": "EUR", "snapshotUrl": "/fairness/box-version/1201/snapshot", "customAttributes": { "is_purchasable": true }, "prizes": [ { "itemId": 906, "name": "Golden Sword", "valueMinor": 320, "currency": "EUR", "imageUrl": "https://cdn…/items/golden-sword-card.png", "odds": 0.05 } ] }}| Field | Notes |
|---|---|
boxId | Integer id; pass to /purchase. |
boxVersionId | The current version. Pass this as the reels[].boxVersionId when you open so the player spins the exact version you showed. |
name | Display name, honouring the requested locale. |
priceMinor, currency | Open price, in the requested currency. |
snapshotUrl | Path to the public fairness snapshot for this version, relative to your operator host. Prefix it with your https://{operator}.app.lootboxsolutions.com origin to link players to it. |
customAttributes | Your custom box attributes (e.g. is_purchasable), with this box’s values. Only declared attributes appear; {} when you’ve declared none. |
prizes[] | One row per item in the box, in the order configured. |
prizes[].itemId | The item id. The same id comes back on a purchase win (reels[].prize.itemId / wonItems[].itemId), so you can map the outcome to the prize tile you rendered. |
prizes[].name | Item name, honouring locale. Names are live, not snapshotted — a rename shows without republishing. |
prizes[].valueMinor, prizes[].currency | Prize value, repriced into the requested currency. The value is frozen to the box’s current version. |
prizes[].imageUrl | Card-size image URL, or null when the item has no image. |
prizes[].odds | Drop probability as a fraction in [0, 1] (e.g. 0.05 = 5%). The rows sum to 1. |
Current version — lightweight lookup
Open the exact version the player saw: pass the boxVersionId you rendered
to /purchase as reels[].boxVersionId. If the box was
republished in the meantime, that version is no longer current and the open is
refused with BOX_NOT_PLAYABLE — surface a “refresh the page and try again”
rather than opening a version whose prizes the player never saw.
To detect that before charging — e.g. to re-render the prize table when a box changed under the player — use the slim companion endpoint:
GET https://{operator}.app.lootboxsolutions.com/api/s2s/boxes/42/version{ "boxVersionId": 1201, "customAttributes": { "is_purchasable": true }}It returns the live boxVersionId plus the box’s
customAttributes — no
prices, FX repricing, or prize list. Compare the version to the one you rendered:
if they differ, your page is stale. The attributes come back here too so a
backend can apply a per-box rule (e.g. gate a purchase on is_purchasable)
against a fresh value at open time, without re-reading the full detail. Same
UNKNOWN_BOX / BOX_NOT_PLAYABLE errors as below.
Errors
| code | HTTP | when |
|---|---|---|
UNKNOWN_BOX | 404 | no box with that id for your operator |
BOX_NOT_PLAYABLE | 409 | the box is inactive or has no published version |
UNSUPPORTED_CURRENCY | 422 | currency is not one of your configured currencies |
Same data, two callers. The game app reads the equivalent in-iframe player-API box detail with a session token. This S2S endpoint is the backend-driven equivalent — same prize table, signed with your API key.