Getting Started
APIs provided by Stash that your backend can call.
What this section is
Stash-hosted endpoints your backend calls.
This is an ingress integration: your backend calls Stash. Stash hosts and maintains these APIs, while you implement the server-side caller in your backend services.
Call Stash API endpoints from your backend only. Do not expose private API keys in game clients.
Keep credentials on the server, call these endpoints from backend code only, and handle auth, retries, and idempotency in your service layer.
Endpoints
Approve custom login
Approves a pending webshop login from your game server. Send the login code the webshop passed to your game, through the login deep link or a QR code, together with the signed-in player as user; Stash then completes the webshop login as that player. Authenticate the request with an HMAC signature of the request body, or with the deprecated API key. This is a server-side endpoint and must not be called from the game client.
Decline custom login
Tells Stash that the game will not approve this login code, and why. A declined code can no longer be approved. This is a server-side endpoint and should not be called from the client.
Force Logout user
Logs out a user by invalidating their session. This endpoint is typically called when a user signs out of the game or switches to another account.
List plans
Lists all available subscription plans for a shop. By default returns only active plans. Use the status filter to include archived or deprecated plans.
Get plan by code
Retrieves a subscription plan by its code (e.g., 'monthly_premium'). Plan codes are unique within a segment.
Get plan by ID
Retrieves a subscription plan by its unique identifier. Returns full plan details including pricing, billing period, and trial configuration.
Force refresh catalog
Refreshes a web shop's cached catalog so the next time a player opens the shop it reflects the latest catalog from your game backend. Applies only to shops with a real-time catalog integration; for any other integration it is a no-op that still returns success. You rarely need to call it: the catalog already refreshes automatically after web shop purchases and free-gift redemptions, and checkout always revalidates against the server. It is most useful after an in-game purchase (outside the web shop) when you want the catalog view in the Web Shop to update right away.
Abort offers
Removes offers from every player's web shop at once, for an offer that has to come down before the catalog cache would drop it (for example a wrong price or wrong contents). Each entry names an offer by the identifier your catalog sends: a purchase pack's id (the whole pack, every price point), a purchasable item's product_id (every per-player variant), or a free or non-purchasable item's item_id. Without a version, the abort hides that offer from every player's catalog, whatever your Get Catalog response returns, until you un-abort it; no catalog is fetched again from your server. With a version that is a whole number written only with the ASCII digits 0 to 9 (for example 5), the abort hides the offer with that identifier at that version and at every lower whole-number version, compared by value: an abort of 10 hides 9, an abort of 5 does not hide 10, and 05 reads as 5. With any other version (for example v5, a version with a sign or spaces, or one using digits other than the ASCII 0 to 9), the abort hides only the offer with exactly that version, compared character for character. Cached catalogs that still hold a hidden version are fetched again from your server on each player's next visit. To bring the offer back fixed, re-publish it under the same identifier with a higher version than the one you aborted: it shows as soon as Get Catalog returns it, with no un-abort needed, while a fix re-published at the aborted version or lower stays hidden. An abort with a version never matches an offer sent without a version. An abort with a version expires 7 days after it was made; an abort without a version lasts until un-aborted. Calls are idempotent: an entry that names an abort already active changes nothing. At most 100 entries per call. A purchase already in checkout when the abort lands can still complete, so Confirm Payment remains your last check. Applies only to shops with a real-time catalog integration and offer aborts enabled; any other shop is refused with FAILED_PRECONDITION.
List offer aborts
Lists every active abort for your shop, including aborts made in Stash Studio, newest first. An abort with a version that has expired is not listed.
Un-abort offers
Removes the aborts each entry names, so those offers show again on each player's next catalog read whenever your Get Catalog response returns them, with no catalog fetched again from your server. An entry removes exactly one abort: an identifier alone removes the abort without a version, and an identifier with a version removes the abort for that version, written as the abort lists it. Versions that another active abort of the same offer still covers stay hidden: removing the abort of 7 while an abort of 5 is active shows versions 6 and 7 again and keeps 5 and lower hidden. It also removes aborts made in Stash Studio. An entry that names no active abort changes nothing. At most 100 entries per call.
Generate Checkout
Generates a quick payment URL for server-side operations. This endpoint is used internally for creating payment links with user information.
Generate authenticated URL
Generates an authenticated webshop URL for a player that signs them in when opened. target selects the page it opens: DEFAULT or ROOT for the webshop's root page, HOME for the home page, STORE for the store page, LOYALTY for the loyalty club page, or DAILY_STREAK for the daily streak page. Authenticate the request with an HMAC signature of the request body, or with the deprecated API key. This is a server-side endpoint and must not be called from the game client.
Get payment event by ID
Retrieves payment details by ID. Returns information about items, pricing, and payment status. This is a server-side endpoint and should not be called from the client.
Get prices
Retrieves uploaded pricing sheet data for the shop associated with the API key, filtered by region. Returns paginated price entries.
Convert prices
Fetches pre-converted prices from the price sheet for the given destination country, applies tax based on region, and optionally applies custom rounding. Returns final prices in minor units and locale-formatted display strings.
Get user preferences
Retrieves the payment channel preference for a specific user. Returns 404 NotFound if no preference is set.
Set user preferences
Creates or updates the payment channel preference for a user. This is a server-side endpoint and should not be called from the client.
List subscriptions
Query subscriptions by player and optionally filter by status. Returns all matching subscriptions for the specified external_account_id.
Get subscription by ID
Retrieves a subscription by its unique identifier. Returns the full subscription object including status, billing period, and dates.
Cancel subscription
Cancels a subscription. By default, access continues until the end of the current billing period (cancel_at_period_end=true). A subscription.canceled webhook is sent and the returned subscription has status 'canceled'. For past_due subscriptions, cancellation is immediate: a single subscription.expired webhook is sent and the returned subscription has status 'expired'.
Get payments by subscription ID
Retrieves payments associated with a subscription with pagination support. Returns a list of payment objects including payment ID, amount, currency, a succeeded indicator, and timestamps. Use the `next_page_token` from the response to fetch the next page.
Reactivate subscription
Reactivates a previously canceled subscription. Only valid before the subscription has expired.
Create a subscription checkout link
Creates a checkout link for purchasing a subscription plan. The link can be shared with users to complete their subscription purchase.
Create a subscription change checkout link
Creates a checkout link for upgrading an existing subscription to a new plan. Only subscriptions in a `active`, `trialing`, or `cancelled` (still within paid period before expiration) state are eligible for upgrades.
Get loyalty program configuration
Retrieves the shop's active loyalty campaign configuration: its tiers (ordered by starting points) and milestones (ordered by points needed). Returns NOT_FOUND when the shop has no active loyalty campaign.
Get loyalty configuration
Retrieves the shop's loyalty configuration in the shape UpdateLoyaltyConfig accepts: display settings, bonus definitions, reward products with their status, and every campaign (season) with its status. Product rewards are returned by SKU. Use it to verify a sync. Returns NOT_FOUND when the shop has no loyalty program.
Configure a loyalty season
Creates or updates one loyalty campaign (season) together with the shop-level display settings, bonus definitions and reward products it depends on, and optionally activates the program. The campaign id is the upsert key: an existing id updates that season, a new id creates one. The request describes the whole season it names, so a tier or milestone omitted from it is removed from that season; bonuses and reward products are created or updated by id or SKU and never removed. Draft and scheduled seasons accept every change. An active season accepts names, descriptions, images, milestone rewards, tier earn rates and a new end date; thresholds, adding or removing tiers or milestones, the start date and reset rules are refused with FAILED_PRECONDITION listing the fields. Ended seasons are read-only. This method accepts only the versioned x-stash-hmac-signature header, signed over the request body exactly as sent; the legacy stash-hmac-signature header is rejected with UNAUTHENTICATED, because it carries no timestamp and a captured request could be replayed. Applying is idempotent: after a 500, resend the same request. Returns INVALID_ARGUMENT with per-field violations when validation fails, FAILED_PRECONDITION also when the shop's loyalty program is bound to more than one shop, PERMISSION_DENIED when the shop is not enabled for configuration writes, ABORTED when another update for the shop is in progress, and NOT_FOUND for an unknown shop.
Get a player's loyalty standing
Retrieves a single player's loyalty standing (points balance, current tier, distance to the next tier and milestone, and effective points multiplier) for the shop's active loyalty campaign. Returns NOT_FOUND when the shop has no active loyalty campaign.
How is this guide?