Box catalog
GET /api/s2s/boxes returns the boxes available to your operator. Use it to build
your own lobby, product grid, or “most popular” widget
(Model B).
Request
GET https://{operator}.app.lootboxsolutions.com/api/s2s/boxesGET https://{operator}.app.lootboxsolutions.com/api/s2s/boxes?page=2&perPage=50GET https://{operator}.app.lootboxsolutions.com/api/s2s/boxes?ids=1,2,3GET https://{operator}.app.lootboxsolutions.com/api/s2s/boxes?sort=-meta.popularity&perPage=12¤cy=EUR&locale=pt-BRGET https://{operator}.app.lootboxsolutions.com/api/s2s/boxes?filter[meta.theme]=fantasy&sort=-price| Query | Notes |
|---|---|
| (none) | All adoptable boxes (active, with a current version), sorted by name — the first page. |
page | Page number, 1-based. Defaults to 1. See Pagination. |
perPage | Page size. Defaults to 100, capped at 200. |
ids | Comma-separated box ids — returns exactly those, regardless of state, so you can re-read previously adopted boxes and detect deactivations. |
filter[<key>] | Spatie query-builder style filter, e.g. filter[slug]=dragon-box or filter[meta.theme]=fantasy. Multiple keys combine with AND; comma-separate values for an OR within one key. Filterable: name, slug, isActive, meta.<key>. |
sort | Ordering — see Sorting. name (default), price, or meta.<key>; prefix with - for descending. |
limit | Alias for perPage, kept for widgets that just cap the strip. |
locale | BCP-47-ish code (e.g. en, pt-BR). Localizes display fields (e.g. name) where a translation exists. Defaults to the operator default. |
currency | ISO-4217 code. Prices come back in this currency; must be one of your configured currencies. Defaults to the operator default. |
Response
{ "boxes": [ { "boxId": 42, "name": "Dragon Box", "slug": "dragon-box", "isActive": true, "isPublished": true, "versionNumber": 7, "priceMinor": 500, "currency": "EUR", "houseEdgeBps": 600, "image": { "alt": "Dragon Box", "webp": "https://cdn…/boxes/dragon.webp", "default": "https://cdn…/boxes/dragon.png" }, "customAttributes": { "is_purchasable": true, "featured_rank": 3 }, "updatedAt": "2026-06-01T09:00:00Z" } ], "pagination": { "page": 1, "perPage": 100, "total": 240, "totalPages": 3, "hasMore": true }}| Field | Notes |
|---|---|
boxId | Integer id; pass to /launches or /purchase. |
name, slug | Display fields. name honours the requested locale where a translation exists. |
image | Image object with pre-converted format variants — webp and default URLs — plus alt. The default keeps the artwork’s original format, preserving transparency. Render a <picture> with the WebP source and the default fallback (see Images). |
isActive, isPublished | Lifecycle flags. |
versionNumber | The current version; pricing/odds belong to a version. |
priceMinor, currency | Open price, in the requested currency. |
houseEdgeBps | House edge in basis points (e.g. 600 = 6%). |
customAttributes | Your custom box attributes — the typed properties you declared, with this box’s values (e.g. is_purchasable). Only declared attributes appear; {} when you’ve declared none. |
updatedAt | Last change, for cache invalidation. |
pagination | The current page’s position — see Pagination. |
Pagination
The catalog is paginated. Each response carries a pagination envelope
alongside boxes:
| Field | Notes |
|---|---|
page | The page you’re on (1-based). |
perPage | The page size in effect (defaults to 100, capped at 200). |
total | Total boxes matching the request, across all pages. |
totalPages | Number of pages at this perPage. |
hasMore | true when another page follows — keep walking. |
To mirror the whole catalog, walk pages until hasMore is false:
GET /api/s2s/boxes?page=1&perPage=200GET /api/s2s/boxes?page=2&perPage=200…until "hasMore": falsePagination composes with filter[…], sort, ids, currency, and locale —
the envelope counts only the boxes matching your filters. A page past the last
one returns an empty boxes array (with hasMore: false), not an error.
Images
The image object ships each box artwork in several formats so you don’t
transcode anything yourself. Use a modern format with a safe fallback:
<picture> <source srcset="{box.image.webp}" type="image/webp" /> <img src="{box.image.default}" alt="{box.image.alt}" loading="lazy" /></picture>Sorting
Pass sort=<key> to order the list. Prefix the key with - for descending;
no prefix is ascending.
sort | Orders by |
|---|---|
name / -name | Box display name. name (ascending) is the default. |
price / -price | Open price in the requested currency. |
meta.<key> / -meta.<key> | A casino-controlled custom box property (meta.*) — e.g. meta.popularity, meta.featured_rank, meta.theme. Boxes without the property sort last. Use -meta.popularity for a curated “most popular” order. |
Combine with perPage for a tidy home-page strip — the first page is all you
need:
GET /api/s2s/boxes?sort=-meta.popularity&perPage=8¤cy=EURBuilding your own lobby
A typical Model-B flow:
- Render your grid from
GET /boxes(walking pages if your catalog is large; cache it; refresh onbox_updated/box_version_publishedwebhooks). - On open, either:
- mint a launch at that
boxIdand embed the iframe, or - read the box’s prize table to render your own box
page, then call
/purchasefrom your backend and render the result yourself.
- mint a launch at that
- For a “Buy now” in a recommended widget,
redirect the player to the box page and
launch with
autoOpento buy + play on arrival — or use a pre-pay purchase so the box auto-opens when the player next lands on it.
Keep prices fresh: a box’s
priceMinorbelongs to its current version. Don’t hard-code prices — read them from the catalog (in the player’s currency) at render time.