Real-time Catalog
Learn how to expose REST API endpoints on your game backend to power personalized web shops with real-time offers. This guide covers the Catalog, Player, and Purchase APIs with protobuf-based type-safe integration.
The Stash v1 WebShop APIs enable game studios to power dynamic, player-personalized web shops with special offers. These protobuf-based APIs provide a robust, type-safe integration path that accelerates development while ensuring reliability at scale.
Getting Started
You can integrate the v1 APIs in two ways. Both produce the same endpoints; pick whichever fits your stack, then follow the Integration Steps below to roll it out.
Clone the proto repository and generate type-safe clients automatically:
# Add the public-api repo as a submodule in your backend repo
git submodule add https://github.com/stashgg/public-api.git
# Or just clone it locally
git clone https://github.com/stashgg/public-api.git
# Generate clients using the included script
cd public-api
./gen.shThe gen.sh script generates clients for Go, TypeScript, and OpenAPI specs. Adapt it for your preferred language (C#, Java, Python, etc.) using standard protobuf tooling.
No documentation required: The generated clients provide full type definitions, so your IDE's autocomplete guides the integration.
Implement the REST endpoints described in the API Reference directly in your preferred language without code generation. This gives you maximum control over your client code at the cost of more upfront work.
The proto repository is still a useful source of truth for field types, enum values, and validation rules, even if you don't run gen.sh.
Integration Steps
Obtain API credentials
Your Stash engineering partner will generate an Egress API key for you in Stash Studio. Set your Game Backend URL in Stash Studio to match where the APIs will be hosted. Custom API endpoint paths can be configured if needed.
Generate clients or review the API reference
Use the proto repository to generate type-safe clients, or review the API Reference for detailed endpoint documentation.
Implement the required endpoints
At minimum, implement these endpoints on your game backend:
Required:
- GetCatalog: Returns the product catalog
- ConfirmPayment: Powers both WebShop and StashPay
Recommended:
For the best multi-platform user experience across the Web Shop & Game Client(s), especially when selling items with limited inventory:
- RegisterPayment: Reserves inventory across all game/shop clients
- CancelPayment: Releases inventory reservation locks
Optional:
- GetOfferDetails: Show extra details like drop rates for legal compliance
- GetPlayer: Show player-specific details like avatar, level, currency
Test with test credentials
Test your integration with your studio-test.stash.gg credentials before going live.
API Overview
The v1 APIs are organized into three services, exposed as REST endpoints. Stash sends requests to your Game Studio's backend servers:
All endpoints use HMAC authentication for secure server-to-server communication.
Catalog API
Retrieve dynamic, player-specific product catalogs.
GetCatalog
GET /api/v1/catalog: returns the complete product catalog for a given platform, region, language, and playerId. The response is structured as sections (grids or carousels) containing PurchasableItem, OfferChainItem, or NonPurchasableItem entries.
For the full request parameters and response schema, see the GetCatalog API Reference.
GetOfferDetails
GET /api/v1/catalog/offer: returns detailed offer information including drop rates for loot boxes, required for legal compliance in many jurisdictions.
For the full request parameters and response schema, see the GetOfferDetails API Reference.
Purchase API
Handle the complete purchase lifecycle with three endpoints.
Purchase Flow
RegisterPayment
POST /api/v1/purchase/register (Step 1): registers a purchase intent. Your backend should reserve inventory for the player and respond with one of the inline status codes (e.g. SUCCESS_REGISTERED, FAILED_INSUFFICIENT_INVENTORY, FAILED_PURCHASE_LIMIT_EXCEEDED, FAILED_INVALID_PRICE).
For the full list of status codes and the complete request/response schema, see the RegisterPayment API Reference.
ConfirmPayment
POST /api/v1/purchase/confirm (Step 2A): confirms and completes the purchase after successful payment. Your backend grants items to the player and acknowledges the transaction.
Unified Integration: This endpoint is the same API used for StashPay integrations. Implement once to power both your WebShop and StashPay checkout links.
For the full request/response schema (including optional fields like extraInGameCurrency, extraLoyaltyPoints, and emailMarketingOptIn), see the ConfirmPayment API Reference.
CancelPayment
POST /api/v1/purchase/cancel (Step 2B, failure path): cancels a pending purchase. Your backend should release reserved inventory so the player can retry.
See the CancelPayment API Reference for the full request/response schema.
Player API
Retrieve player profile information for personalized experiences.
GetPlayer
GET /api/v1/player: returns player profile data (name, avatar, language, in-game level, in-game currency) for display in the web shop. Stash calls this endpoint with the playerId you supplied to the catalog request.
See the GetPlayer API Reference for the full request/response schema.
Key Data Types
Catalog Items
The catalog supports three item types using protobuf oneof:
| Type | Use Case |
|---|---|
| PurchasableItem | Standard products and bundle offers with pricing |
| OfferChainItem | Progressive offers that unlock sequentially with CLAIMED / UNLOCKED / LOCKED link statuses |
| NonPurchasableItem | Banners, promotions, and informational displays |
For the full field-level structure of each type, including pricing, contents, expiration, attributes, and offer chain link details, see the GetCatalog API Reference.
Localization
All user-facing text supports localization. For each text field you can return either (but not both):
localizationKey: Stash-side lookup in our localization system (requires sharing localization keys with Stash up front).localizedText: Pre-resolved text in the player's language, computed by your backend.
Pick whichever fits your localization pipeline; you can mix the two across different fields in the same response.
Web Store Bonuses
Incentivize web purchases with bonus content:
| Feature | Description |
|---|---|
| Bonus Items | Extra items added exclusively for web purchases |
| Bonus Quantities | Percentage increases on item quantities |
| Visual Indicators | ContentItemType.WEB_STORE_BONUS for UI highlighting |
Drop Rate Compliance
For loot boxes and randomized rewards, the API supports drop rate disclosure required for legal compliance in many jurisdictions.
Enabling Drop Rate Display
To show drop rates or offer details in a popup:
-
Add a badge with the show details action: Include a badge on the offer with
action: BADGE_ACTION_SHOW_OFFER_DETAILS. This signals to the frontend to display an info button that calls the GetOfferDetails API and opens the corresponding modal. -
Enable per-item details (optional): For individual content items that should show their own reward/drop rate details, include
clickAction: CONTENT_ITEM_CLICK_ACTION_SHOW_DETAILS_BY_IDon thatContentItem.
Example Catalog.PurchasableItem Response
{
"attributes": {
"badge": {
"text": { "defaultText": "Loot Box" },
"action": "BADGE_ACTION_SHOW_OFFER_DETAILS"
}
},
"contents": [
{
"name": "Legendary Hero",
"guid": "xxx",
"image": "https://...",
"quantity": "1",
"dropRate": "2.5%",
"clickAction": "CONTENT_ITEM_CLICK_ACTION_SHOW_DETAILS_BY_ID"
},
{
"name": "Common Item",
"quantity": "1",
"dropRate": "97.5%"
}
]
}If using clickAction, the guid must be supplied (can't be auto-generated)
to cross-reference with the GetOfferDetails API response.
Caching
Stash caches the catalog response your server returns. This reduces load on your catalog server and improves shop load times for players.
Caching is enabled by default for all Real-time Catalog integrations. If you wish to disable it temporarily for testing purposes, let your engineering partner at Stash know.
How long are responses cached?
The effective cache lifetime is:
min(5 minutes, earliest upcoming timestamp in your response)Stash inspects every refresh and expiration timestamp in your response (offer refresh times, offer and item expirations, section display expirations, and scheduled resets such as a midnight-UTC daily offer rollover) and caps the cache at the earliest one. Stash only ever shortens the window from these signals; it never serves a cached response past the point your response indicated.
The default cap is 5 minutes when your response contains no timestamp signals.
Recommended pattern for timed catalog resets: set the refresh or expiration timestamp equal to your planned reset time. Stash re-fetches exactly at that boundary, so there is no perceptible delay when the catalog changes.
Immediate invalidation after player actions
Stash clears a player's cached catalog immediately after every non-read action:
- Purchases
- Free-gift redemptions
- Loyalty-milestone claims (where integrated)
The next shop load re-fetches live from your server. No special annotation or forced reload is needed. This is automatic.
Always-fresh Stash-side data
Only the raw response from your catalog API is cached. Data that Stash computes (prices, bonuses, offer-chain and purchase-progression state, injected free offers) is recomputed on every request and is never cached. Changes you make to prices or bonuses in Stash Studio are reflected immediately regardless of the cache window.
Frequently asked questions
Does Stash cache the response my server returns?
Yes. Stash caches your catalog/offer response for a short, bounded window. This reduces load on your catalog server and speeds up the shop for players.
What is the worst-case staleness? How long is my data cached?
min(5 minutes, earliest refresh/expiration timestamp in your response). Without any timestamp signals in your response, responses may be served for up to 5 minutes.
How do I make a catalog change appear at a known time, such as a daily reset?
Include the planned reset time as the refresh or expiration timestamp in your response. Stash re-fetches exactly at that boundary with no delay.
What happens after a player makes a purchase?
The player's cached catalog is cleared immediately on every purchase, free-gift redemption, and loyalty-milestone claim. The next shop visit re-fetches live from your server. This is automatic. No special annotation is needed.
Do I need to send Cache-Control HTTP headers?
No. Stash does not use HTTP Cache-Control headers for this. Control freshness via refresh and expiration timestamps in your catalog payload instead.
Can the cache show a player an offer they already purchased?
The window is short, and Stash performs a fresh server-side check before completing any purchase or redemption. Stale attempts are rejected before they reach your server, so players cannot buy something that is no longer available. To minimize the visual window further, include accurate expiration or refresh timestamps in your response.
My catalog has offers with different refresh times. How should I structure the timestamps?
Include the earliest upcoming refresh or expiration timestamp across the catalog. Stash caps the cache lifetime to that value. Ideally align all refreshes to a single consistent reset time so the whole catalog expires together.
Can caching be turned off while I test catalog changes?
Yes. Contact your Stash engineering partner and they will disable caching for your test shop, so every request hits your server live.
What are the benefits of caching?
Faster shop loads for players, fewer requests to your catalog server, and improved reliability if your server is briefly slow or unavailable.
Authentication
All API calls use HMAC-SHA256 signatures for authentication:
Header: stash-hmac-signature
Value: HMAC-SHA256(request_body, BASE64(egress_api_key))Your base64-encoded Egress API key obtained from Stash Studio is the secret used to sign the request body.
If you've implemented HMAC authentication and your game backend is still
responding to Stash's API requests with 3xx, 4xx, or 5xx error codes, you may
need to allowlist test-api.stash.gg and api.stash.gg on your cloud network
firewall.
Configuration
To configure your Real-time Catalog endpoint in Stash Studio:
Navigate to game settings
In Stash Studio, navigate to your game settings.
Open App Backend
Go to Project Settings → App Backend
Set endpoint URL
Set your Game Backend URL to match where the Catalog & Purchase APIs will be hosted.
Configure authentication
Your Stash engineering partner can configure custom API endpoint paths if needed.
Debugging & Logs
Stash Studio provides comprehensive logging and debugging tools for your Real-time Catalog. Use these tools to monitor your catalog endpoint and troubleshoot issues:
- Check Stash Studio logs for endpoint response times
- Verify your endpoint returns valid JSON
- Ensure all required fields are present
- Test with your studio-test credentials before going live
How is this guide?