Dynamic Catalog
Learn how to expose REST API endpoints on your game backend to power dynamic, player-personalized web shops with special 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.
Why Protobuf-Based APIs?
| Benefit | Impact |
|---|---|
| Type Safety | Compile-time validation catches integration errors before deployment |
| Auto-generated Documentation | Always up-to-date API docs from proto definitions |
| Multi-language Support | Generate clients in Go, TypeScript, C#, Java, Python, and more |
| Faster Integration | ~2 weeks faster integration vs implementing REST APIs by hand |
| Backward Compatibility | Proto versioning ensures smooth API evolution |
Getting Started
Step 1: Auto-generate Clients (Recommended)
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.
Step 2: Implement the REST APIs
Implement the REST endpoints that Stash will call. You can either use the API Reference to write your own clients or generate clients automatically from the protobufs.
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
Returns the complete product catalog with purchasable items, offer chains, and display elements.
Endpoint: GET /api/v1/catalog
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
platform | enum | IOS, ANDROID, or WEBSTORE — enables platform-specific pricing |
region | string | ISO-3166-1 alpha-2 code (e.g., US, GB, DE) for localized pricing |
language | string | ISO 639-1 code (e.g., en, es, fr) for localized text |
playerId | string | Player ID for personalized offers and purchase limits |
Response Structure:
Catalog
└── Sections[]
├── header (LocalizableText)
├── displayType (GRID or CAROUSEL)
└── items[]
├── PurchasableItem (products & bundles)
├── OfferChainItem (progressive unlocks)
└── NonPurchasableItem (banners & info)See the full GetCatalog API Reference for detailed response schema.
GetOfferDetails
Returns detailed offer information including drop rates for loot boxes (required for legal compliance in many jurisdictions).
Endpoint: GET /api/v1/catalog/offer
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
guid | string | Unique offer instance identifier |
productId | string | Product SKU |
platform | enum | Platform for price resolution |
region | string | Region for localization |
language | string | Language for text |
playerId | string | Player ID for personalization |
See the full GetOfferDetails API Reference for detailed response schema.
Purchase API
Handle the complete purchase lifecycle with three endpoints.
Purchase Flow
RegisterPayment
Step 1: Registers a purchase intent. Your backend should reserve inventory for the player.
Endpoint: POST /api/v1/purchase/register
Key Fields:
| Field | Description |
|---|---|
playerId | Player making the purchase |
transactionId | Unique transaction identifier (generated by Stash) |
currency | ISO-4217 currency code (e.g., USD, EUR) |
registrations[] | Items to purchase with productId, quantity, cents |
platform | IOS, ANDROID, or WEBSTORE |
source | CART (web shop) or DIRECT (StashPay checkout link) |
Response Status Codes:
| Status | Meaning | Action |
|---|---|---|
SUCCESS_REGISTERED | Inventory reserved | Proceed to payment |
FAILED_INVALID_OFFER | Offer expired or invalid | Show error, refresh catalog |
FAILED_INSUFFICIENT_INVENTORY | Not enough stock | Show error, update UI |
FAILED_PURCHASE_LIMIT_EXCEEDED | Player limit reached | Show limit info to player |
FAILED_INVALID_PRICE | Price mismatch | Refresh pricing |
FAILED_PURCHASE_LOCKED | Purchase restricted | Show restriction message |
See the full RegisterPayment API Reference for detailed request/response schema.
ConfirmPayment
Step 2A: Confirms and completes the purchase after successful payment.
Unified Integration: This endpoint is the same API used for StashPay integrations. Implement once to power both your WebShop and StashPay checkout links.
Endpoint: POST /api/v1/purchase/confirm
Key Fields:
| Field | Description |
|---|---|
playerId | Player who completed purchase |
transactionId | Transaction ID from registration |
currency | Currency code |
tax | Tax amount in cents |
total | Total amount including tax in cents |
timeMillis | Completion timestamp (Unix millis) |
items[] | Purchased items with final pricing |
extraInGameCurrency | Optional bonus currency to grant |
extraLoyaltyPoints | Optional bonus loyalty points |
emailMarketingOptIn | Customer marketing preference |
See the full ConfirmPayment API Reference for detailed request/response schema.
CancelPayment
Step 2B: Cancels a pending purchase. Your backend should release reserved inventory.
Endpoint: POST /api/v1/purchase/cancel
See the full CancelPayment API Reference for detailed request/response schema.
Player API
Retrieve player profile information for personalized experiences.
GetPlayer
Returns player profile data for display in the web shop.
Endpoint: GET /api/v1/player
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
playerId | string | Player ID to retrieve |
Response Example:
{
"player": {
"playerId": "abc123",
"name": "PlayerOne",
"avatarUrl": "https://...",
"language": "en",
"inGameLevel": 42,
"inGameCurrency": 15000
}
}See the full GetPlayer API Reference for detailed response schema.
Coming Soon: Loyalty Data
The Player API will soon include loyalty program data to power rich loyalty experiences:
| Field | Description |
|---|---|
loyalty.currentTier | Current loyalty tier/level |
loyalty.totalPoints | XP accumulated so far |
loyalty.currencyAmount | Spendable loyalty currency balance |
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 |
| NonPurchasableItem | Banners, promotions, and informational displays |
PurchasableItem Structure
PurchasableItem
├── productId (required) - Your unique SKU
├── guid (optional) - Instance UUID for dynamic offers
├── type - STANDARD_OFFER or BUNDLE_OFFER
├── name/description (LocalizableText)
├── image - Product image URL
├── price
│ ├── amount.currency - ISO currency code
│ └── amount.cents - Price in smallest unit
├── maxPurchasable - Per-player purchase limit
├── expiration - Offer end timestamp
├── contents[] - Items included in purchase
│ ├── name, image, quantity
│ ├── bonusQuantity - Web store bonus amount
│ └── dropRate - For legal compliance
└── attributes
├── banner - Promotional banner text
├── badge - Corner badge (e.g., "NEW", "50% OFF")
├── background - Custom styling
└── buyButton - CTA customizationOffer Chains
Progressive offers encourage repeat purchases:
OfferChainItem
└── links[]
├── status: CLAIMED (purchased)
├── status: UNLOCKED (available)
└── status: LOCKED (requires previous)Localization
All user-facing text supports localization:
{
"defaultText": "Special Bundle",
"localizationKey": "offer.special_bundle.title",
"localizedText": "Offre Spéciale"
}Choose between:
- localizationKey: Stash-side lookup in our localization system (requires sharing locKeys)
- localizedText: Pre-resolved server-side text
Integration Considerations
When to Use Each Endpoint
| Scenario | Endpoints Used |
|---|---|
| Initial page load | GetCatalog + GetPlayer |
| Player clicks "View Details" | GetOfferDetails |
| Player starts checkout | RegisterPayment |
| Rewards granted successfully | ConfirmPayment |
| Rewards failed to grant | CancelPayment |
Caching Strategy
| Data | Recommended TTL | Notes |
|---|---|---|
| Catalog structure | 1-5 minutes | Balance freshness vs. load |
| Player data | 30 seconds | Keep profile current |
| Offer details | 5 minutes | Drop rates rarely change |
| Prices | Real-time | Always fetch current prices |
Error Handling
- Catalog API: Returns empty sections for unavailable content
- Purchase API: Uses inline status codes (always HTTP 200) for predictable error handling
- Player API: Returns 404 for unknown players
Platform & Region Pricing
Price Resolution
Prices can vary by platform and region. The API resolves the correct price based on:
| Factor | Impact |
|---|---|
| Platform | Different prices for iOS, Android, and Web (web often offers better margins) |
| Region | Localized currency and regional pricing strategies |
| Player Context | Personalized offers based on player behavior and segments |
Platform Values
| Value | Description |
|---|---|
CATALOG_PLATFORM_IOS | iOS App Store pricing |
CATALOG_PLATFORM_ANDROID | Google Play pricing |
CATALOG_PLATFORM_WEBSTORE | Web shop pricing (typically lower fees) |
Price ID vs Price Amount
When returning prices in the catalog, you have two options:
- Your backend calculates and returns the exact price in the player's currency
- Full control over pricing logic and regional strategies
- Requires your backend to maintain price tables for all supported currencies
Best for: Studios managing their own pricing tables
- Share your price IDs and corresponding prices in various currencies with Stash
- Stash manages the price lookup based on player region and platform
- Simplifies your backend — just return the price ID, and Stash handles currency conversion
- Easier to update prices without code changes
Best for: Studios wanting Stash to manage regional & platform prices
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.
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 dynamic catalog endpoint in Stash Studio:
Navigate to game settings
In Stash Studio, navigate to your game settings.
Open Configuration
Go to Webshop → Configuration
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 dynamic 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?
Managed Catalog
Learn how to launch a Stash webshop without writing code using the managed catalog. Manage your catalog directly in Stash Studio or through API calls for automated updates and synchronization with other systems.
Authentication Methods
Learn about the two methods for authenticating players in your Stash webshop - Direct Sign-in (SSO) using providers like Google, Apple, or Facebook, and Account Linking through deep links and QR codes for passwordless authentication.