# Thrillzz Jackpots — Developer Portal (full) Generated from the portal's content sources. HTML version: https://docs.jackpots-platform.io/ · Index: https://docs.jackpots-platform.io/llms.txt ## How to use this document - To show jackpots in an operator **lobby today**, use the **Current** section: Ticker `GET /v2/counters` plus Win History `GET /api/v3/WinHistory/product/{productId}/recent` and `/summary`. No authentication, no game identifiers. Or drop in the reference widget below. - Lead with what operators care about: the **value and volume of wins paid out over a period** (sum `totalWinAmountCents` and `triggerCount` from `/summary`), then recent winners, then live pot values. - Anything under **Future** (lobby opt-in, Widget, Gameplay API) is specified but not integrable today. - Hosts are placeholders `{{TICKER_API}}`, `{{WINHISTORY_API}}`, `{{PLAYERCONTEXT_API}}`, `{{GAMEPLAY_API}}` — substitute from the Environments table. ## Editions ### Current Available today — live jackpot values and win history for a lobby. This is the Current edition: what a lobby can integrate against today, either by dropping in the reference Lobby Widget or by calling the feeds directly. The lobby reads live jackpot values from the Ticker API, and recent wins plus period win totals from the Win History API. Both are unauthenticated, and both are scoped by game today (productId + moduleId + clientId) — the product-only routes are specified but not yet deployed. Player opt-in from the lobby is Future. ### Future Coming next — lobby opt-in, the Widget and server-side opt-in wagering. This is the Future edition: everything in Current plus lobby opt-in and server-side opt-in wagering. The Gameplay API lets a game server raise an opt-in wager per round (prePlay / play), so mystery and progressive jackpots can be attached to any game while the platform owns jackpot state. ## Environments Current (lobby) hosts: | Environment | Ticker API | Win History API | | --- | --- | --- | | Staging | https://jackpotbridgeticker29.gameassists.co.uk | https://jackpotwinhistory29.gameassists.co.uk | | Production | https://jackpotbridgeticker.gameassists.co.uk | https://jackpotwinhistory.gameassists.co.uk | All hosts (Future adds Player Context and Gameplay): | Environment | Ticker API | Win History API | Player Context API | Gameplay API | | --- | --- | --- | --- | --- | | Staging | https://jackpotbridgeticker29.gameassists.co.uk | https://jackpotwinhistory29.gameassists.co.uk | https://jackpotplayercontext29.gameassists.co.uk | https://jackpotgameplay29.gameassists.co.uk | | Production | https://jackpotbridgeticker.gameassists.co.uk | https://jackpotwinhistory.gameassists.co.uk | https://jackpotplayercontext.gameassists.co.uk | https://gameplay.jackpots-platform.io | ## Authentication - Ticker API — no authentication; answers browser calls with `Access-Control-Allow-Origin: *` today (a per-environment origin allowlist is supported). The `productId`, `moduleId` and `clientId` a lobby passes are issued by the Jackpots team (ThrillzzJackpots@gamesglobal.com) — they are not published or discoverable from the feeds, so ask for the set covering the games you are showing. - Win History API — no authentication; same CORS arrangement as the Ticker API (`*` today). - Player Context API (Future) — `GET /optin` unauthenticated; `PUT /optin` requires a player-session Bearer token and returns 403 if the body's `playerId` does not match the token. - Gameplay API (Future) — OAuth2 client-credentials. ## Feed rules — read before writing code - `GET /v2/counters` values `startAtValue` / `endAtValue` are **currency units** (e.g. `13842.74` EUR). `centsPerSecond` and every Win History `*Cents` field are **cents**. Never divide counters values by 100. - `endAtValue` is the next animation checkpoint (reached after `numberOfSeconds`), **not a cap**. Animate from `startAtValue` at `centsPerSecond / 100` per second and clamp at `endAtValue`, then re-poll. - `jackpotType` is an integer, and it is per level and set by configuration — read it per row rather than assuming it from the level's name. `2` = must be won: show progress toward the ceiling `jackpotMaxAmountCents / 100`. Any other type (e.g. `3`, which Jackpot Madness's Madness level returns) has no ceiling and its `jackpotMaxAmountCents` is a sentinel (live: ~1.17e10) — never show a ceiling for those. Live on 2026-09-16, one Jackpot Madness game returned Madness as `3` and Mayhem, Mania and all three Mystery levels as `2`; the Mystery levels reported `3` the day before, so branch on the value you are handed. - Win History composes `progressiveId` from the site id and the level id, so it equals the ticker's raw level id (live range ~20047–20213) only while the site id is zero — what production returns for the live series today (verified 2026-09-15). Do not build on the ids matching: label wins by `levelIndex` (0-based), which is the ticker's `gamePayId`. - The version is a literal path segment and `counters` is **v2 only** — `GET /v1/counters` returns `404`. v1 exposes `GET /v1/ticker` instead (different parameters, different shape). Paths in this document are callable as written; do not substitute a version into them. - Both feeds answer `GET /health` with `200 Healthy`, unauthenticated and parameterless — use it to confirm reachability before debugging a call. - A game module can carry pools of several jackpot series. Filter `/v2/counters` rows by `jackpotName` (e.g. `MADNESS`, `MAYHEM`, `MANIA`, `MYSTERY` for Jackpot Madness). `friendlyName` is the **game** name — never group by it. - Counters echoes `productId` only when you pass it — called without one, every row comes back `productId: null`. Scope with the `productId` / `moduleId` query parameters rather than filtering client-side. - `/v2/counters` is output-cached 2s server-side; **both** Win History route shapes are output-cached 300s with a 120s invalidation delay, so a fresh win can take minutes to appear. Poll no faster. - A ticker `400` can mean the tickers circuit breaker tripped — treat it as "retry shortly". - The game-scoped Win History routes (`/api/v3/WinHistory/recent|summary|overview`) require **all** of `ModuleId`, `ClientId`, `ProductId` and `CurrencyIsoCode`. Omitting any one returns 400 (`{"productId":["ProductId must be a positive number."]}`) — the OpenAPI export marks them optional, which is wrong. The product-scoped routes take the product in the path and need no game ids. - The product-scoped Win History routes (`/api/v3/WinHistory/product/{productId}/recent|summary|overview`) are **not deployed yet** — they return `404` on Staging and Production (verified 2026-09-15). Integrate against the game-scoped routes; the response shapes are the same. ## Key concepts - `productId` — the operator product (casino) a jackpot link belongs to. - `progressiveId` — a specific progressive jackpot level within a link (see the id mismatch above). - Levels — a jackpot (e.g. Jackpot Madness: Madness, Mayhem, Mania + three Mystery levels) is a set of levels; each `/counters` row is one level, named by `jackpotName`. Level indexes are 0-based: a win carries `levelIndex`; Win History filters on `LevelIndexes`. - `jackpotNumber` — a running number for a level's jackpot instances; it advances each time that level is won. - Jackpot Madness — the opt-in Express Jackpots product (players stake a small extra amount per bet to join). Lotsaloot — the base Express Jackpots product, funded from every bet, no opt-in. --- # CURRENT edition — API reference Exactly what a lobby can integrate today: game-scoped (productId + moduleId + clientId) on the routes that answer, plus the product-scoped shape that is specified but not yet deployed. ## Ticker API Live jackpot values for a lobby — GET /counters. Versions: v2. Host token: `{{TICKER_API}}`. ### `GET /v2/counters` (v2) Handles GET requests for lobby tickers. The lobby ticker list — jackpot level values for display in the lobby. `counters` exists on v2 only: `GET /v1/counters` returns `404`, and v1's equivalent is the differently-shaped `GET /v1/ticker`. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `productId` | query | integer | no | | | `moduleId` | query | integer | no | | | `currencyIsoCode` | query | string | yes | | Responses: - `200` — `LobbyTickerResponse[]` — OK - `400` — `ProblemDetails` — Bad Request - `500` — `ErrorResponseOfError` — Internal Server Error `200` response (real production body): ```json [ { "progressiveId": 20153, "productId": 16755, "moduleId": 18661, "gamePayId": 0, "startAtValue": 18805.84, "endAtValue": 18812.85, "numberOfSeconds": 600, "centsPerSecond": 1, "currencyIsoCode": "EUR", "friendlyName": "9 Masks of Fire v94", "jackpotNumber": 23, "triggerCount": 22, "secondsSinceLastWin": 103199, "rtp": 5, "jackpotName": "MADNESS", "jackpotType": 3, "jackpotMaxAmountCents": 1169066464783, "rtpPercentages": { "OptIn": 5 } }, { "progressiveId": 20154, "productId": 16755, "moduleId": 18661, "gamePayId": 1, "startAtValue": 164.80, "endAtValue": 171.81, "numberOfSeconds": 600, "centsPerSecond": 1, "currencyIsoCode": "EUR", "friendlyName": "9 Masks of Fire v94", "jackpotNumber": 8864, "triggerCount": 8863, "secondsSinceLastWin": 754, "rtp": 10, "jackpotName": "MAYHEM", "jackpotType": 2, "jackpotMaxAmountCents": 23381, "rtpPercentages": { "OptIn": 10 } } ] ``` Notes: - `currencyIsoCode` is required. Pass `productId` and `moduleId` together to scope a lobby to one product and game — a module alone returns every link group it touches, repeated per game sharing each pool. - `startAtValue` and `endAtValue` are currency units (e.g. `13842.74` EUR), not cents — only `centsPerSecond` is cents. `endAtValue` is the next animation checkpoint, never a ceiling. - Animate client-side from `startAtValue` to `endAtValue` at `centsPerSecond` rather than polling for every intermediate value — `/v2/counters` is output-cached for 2s server-side. Fetch lobby counters: ```typescript const response = await fetch( `{{TICKER_API}}/v2/counters?productId=${productId}&moduleId=${moduleId}¤cyIsoCode=EUR`, ); const counters = await response.json(); // Animate each counter from startAtValue to endAtValue at centsPerSecond client-side. ``` ### Ticker API — schemas #### `EJackpotType` _No fields._ #### `Error` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `application` | string | yes | | | `message` | string | yes | | | `description` | string | yes | | #### `ErrorResponseOfError` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `errors` | Error[] (see `Error`) | no | | #### `ProblemDetails` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `type` | string | no | nullable | | `title` | string | no | nullable | | `status` | integer | no | nullable | | `detail` | string | no | nullable | | `instance` | string | no | nullable | #### `LobbyTickerResponse` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `progressiveId` | integer | no | | | `productId` | integer | no | nullable | | `moduleId` | integer | no | nullable | | `gamePayId` | integer | no | | | `startAtValue` | number | no | | | `endAtValue` | number | no | | | `numberOfSeconds` | number | no | | | `centsPerSecond` | integer | no | nullable | | `currencyIsoCode` | string | yes | | | `friendlyName` | string | yes | | | `jackpotNumber` | integer | no | nullable | | `triggerCount` | integer | no | | | `secondsSinceLastWin` | integer | no | nullable | | `rtp` | number | no | nullable | | `jackpotName` | string | yes | | | `jackpotType` | EJackpotType (see `EJackpotType`) | no | | | `jackpotMaxAmountCents` | number | no | | | `rtpPercentages` | Record | no | | ## Win History API Recent wins and period win totals for every jackpot behind a game — game-scoped today, product-scoped once the new routes deploy. Versions: v3. Host token: `{{WINHISTORY_API}}`. ### `GET /api/v3/WinHistory/recent` (v3) Handles the request to get recent wins v3. The most recent jackpot wins for a game, newest first — live in production today, and what a lobby's recent-winners strip calls until the product-scoped route deploys. The brief refers to this endpoint as `/api/v3/winhistory/recent` (lowercase); the generated key preserves the OpenAPI spec's casing (`WinHistory`), so this overlay attaches to that key. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `LevelIndexes` | query | integer[] | no | List of level index to return win values. | | `Count` | query | integer | no | Count of records to be returned. Default: 100. Limit: 100.; min 1; max 100 | | `ModuleId` | query | integer | no | min 1; max 2147483647 | | `ClientId` | query | integer | no | min 1; max 2147483647 | | `ProductId` | query | integer | no | min 1; max 2147483647 | | `CurrencyIsoCode` | query | string | no | pattern `^[A-Za-z]{3}$` | Responses: - `200` `200` response (real production body): ```json [ { "winDateTime": "2026-09-15T13:09:50.2736061+02:00", "winAmountCents": 2338, "jackpotInstanceId": 1557771, "progressiveId": 20156, "levelIndex": 3, "triggerCount": 96063 }, { "winDateTime": "2026-09-15T13:09:39.9550911+02:00", "winAmountCents": 1753, "jackpotInstanceId": 1557770, "progressiveId": 20157, "levelIndex": 4, "triggerCount": 213404 } ] ``` Notes: - `ModuleId`, `ClientId` and `ProductId` are all required in practice — the spec marks them optional, but the service returns `400` ("ClientId must be a positive number") when any one is missing. - `Count` ranges from 1–100 (default 100); `LevelIndexes` (repeatable) narrows to specific levels — unfiltered, frequent levels swamp rare ones. - Output-cached for 300s with a 120s invalidation delay — a fresh win can take a couple of minutes to appear. - `progressiveId` is composed from the site id and the level id, so it equals the raw level id `/v2/counters` emits only while the site id is zero — which is what production returns for the live series today (verified 2026-09-15). Match wins to levels by `levelIndex` (the ticker's `gamePayId`) rather than joining on `progressiveId`. Fetch recent wins: ```typescript const response = await fetch( `{{WINHISTORY_API}}/api/v3/WinHistory/recent` + `?ModuleId=${moduleId}&ClientId=${clientId}&ProductId=${productId}&CurrencyIsoCode=EUR&Count=20`, ); const recentWins = await response.json(); ``` ### `GET /api/v3/WinHistory/summary` (v3) Handles the request to get summary of wins v3. Per-level win totals for a game over a period — live in production today. The value and volume an operator lobby leads with: one row per jackpot level, so sum `totalWinAmountCents` and `triggerCount` across rows for the headline. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `LevelIndexes` | query | integer[] | no | List of level index to return win values. | | `FromDate` | query | string (date-time) | no | Starting date to fetch data from | | `ToDate` | query | string (date-time) | no | Ending date to fetch data to. Default: Now | | `ModuleId` | query | integer | no | min 1; max 2147483647 | | `ClientId` | query | integer | no | min 1; max 2147483647 | | `ProductId` | query | integer | no | min 1; max 2147483647 | | `CurrencyIsoCode` | query | string | no | pattern `^[A-Za-z]{3}$` | Responses: - `200` `200` response (real production body): ```json [ { "progressiveId": 20156, "levelIndex": 3, "triggerCount": 1551, "triggerCountAllTime": 27758, "totalWinAmountCents": 3620563, "highestWinAmountCents": 2338, "avgWinAmountCents": 2334, "avgWinTimeSeconds": "00:01:12.6634429", "lastJackpotInstanceId": 1556367 }, { "progressiveId": 20158, "levelIndex": 5, "triggerCount": 2919, "triggerCountAllTime": 54045, "totalWinAmountCents": 3406253, "highestWinAmountCents": 1169, "avgWinAmountCents": 1166, "avgWinTimeSeconds": "00:00:38.5251798", "lastJackpotInstanceId": 1556359 } ] ``` Notes: - `ModuleId`, `ClientId` and `ProductId` are all required in practice, as on `/recent`. - Omit `FromDate` for all-time totals; `ToDate` defaults to now. `LevelIndexes` (repeatable) narrows the levels. - Output-cached for 300s with a 120s invalidation delay — a fresh win can take a couple of minutes to appear. - `avgWinTimeSeconds` is a TimeSpan string, e.g. `"02:14:07"`. Paid out in the last 24h: ```typescript const to = new Date(); const from = new Date(to.getTime() - 24 * 60 * 60 * 1000); const response = await fetch( `{{WINHISTORY_API}}/api/v3/WinHistory/summary` + `?ModuleId=${moduleId}&ClientId=${clientId}&ProductId=${productId}&CurrencyIsoCode=EUR` + `&FromDate=${from.toISOString()}&ToDate=${to.toISOString()}`, ); const rows = await response.json(); const paidOutCents = rows.reduce((sum, r) => sum + r.totalWinAmountCents, 0); const winCount = rows.reduce((sum, r) => sum + r.triggerCount, 0); ``` ### `GET /api/v3/WinHistory/product/{productId}/recent` (v3) Handles the request to get recent wins across every jackpot a product contributes to, without naming a game. Recent wins across every jackpot a product contributes to, without naming a game — the lobby's recent-winners feed. The product is a path segment; everything else is query. A jackpot reachable through more than one link group is counted once. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `ProductId` | path | integer | yes | The product/brand to return wins for.; min 1; max 2147483647 | | `CurrencyIsoCode` | query | string | no | The currency code to return the win values in. The code is in ISO 4217 format.; pattern `^[A-Za-z]{3}$` | | `LevelIndexes` | query | integer[] | no | List of level index to return win values. | | `ProgressiveIds` | query | integer[] | no | Restricts the response to these jackpots. Ids are the `progressiveId` values the ticker's `/v2/counters` feed returns, so a lobby can pass straight through what it already holds. Omit to return every jackpot the product reaches. | | `Count` | query | integer | no | Count of records to be returned. Default: 100. Limit: 100.; min 1; max 100 | Responses: - `200` `200` response (real production body): ```json [ { "winDateTime": "2026-09-15T13:09:50.2736061+02:00", "winAmountCents": 2338, "jackpotInstanceId": 1557771, "progressiveId": 20156, "levelIndex": 3, "triggerCount": 96063 }, { "winDateTime": "2026-09-15T13:09:39.9550911+02:00", "winAmountCents": 1753, "jackpotInstanceId": 1557770, "progressiveId": 20157, "levelIndex": 4, "triggerCount": 213404 } ] ``` Notes: - `Count` ranges from 1–100 (default 100); `LevelIndexes` and `ProgressiveIds` (both repeatable) narrow to specific levels. - `progressiveId` is composed from the site id and the level id, so it equals the raw level id `/v2/counters` emits only while the site id is zero — which is what production returns for the live series today (verified 2026-09-15). Match wins to levels by `levelIndex` (the ticker's `gamePayId`) rather than joining on `progressiveId`. - Output-cached for 300s with a 120s invalidation delay — a lobby strip can be up to ~5 minutes behind. - Not deployed yet — returns `404` on Staging and Production today. Integrate against the game-scoped `/api/v3/WinHistory/recent`, which returns the same shape. Recent winners for a product: ```typescript const response = await fetch( `{{WINHISTORY_API}}/api/v3/WinHistory/product/${productId}/recent?CurrencyIsoCode=EUR&Count=10`, ); const wins = await response.json(); // [{ progressiveId, levelIndex, triggerCount, winDateTime, winAmountCents, jackpotInstanceId }] ``` ### `GET /api/v3/WinHistory/product/{productId}/summary` (v3) Handles the request to get a win summary across every jackpot a product contributes to, without naming a game. Per-level win totals for a product over a period, without naming a game — what an operator lobby leads with: the value and volume of wins paid out. One row per jackpot level; sum `totalWinAmountCents` and `triggerCount` across rows for the headline. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `ProductId` | path | integer | yes | The product/brand to return the summary for.; min 1; max 2147483647 | | `CurrencyIsoCode` | query | string | no | The currency code to return the win values in. The code is in ISO 4217 format.; pattern `^[A-Za-z]{3}$` | | `LevelIndexes` | query | integer[] | no | List of level index to return win values. | | `ProgressiveIds` | query | integer[] | no | Restricts the response to these jackpots. Ids are the `progressiveId` values the ticker's `/v2/counters` feed returns, so a lobby can pass straight through what it already holds. Omit to return every jackpot the product reaches. | | `FromDate` | query | string (date-time) | no | Starting date to fetch data from. | | `ToDate` | query | string (date-time) | no | Ending date to fetch data to. Default: Now. | Responses: - `200` `200` response (real production body): ```json [ { "progressiveId": 20156, "levelIndex": 3, "triggerCount": 1551, "triggerCountAllTime": 27758, "totalWinAmountCents": 3620563, "highestWinAmountCents": 2338, "avgWinAmountCents": 2334, "avgWinTimeSeconds": "00:01:12.6634429", "lastJackpotInstanceId": 1556367 }, { "progressiveId": 20158, "levelIndex": 5, "triggerCount": 2919, "triggerCountAllTime": 54045, "totalWinAmountCents": 3406253, "highestWinAmountCents": 1169, "avgWinAmountCents": 1166, "avgWinTimeSeconds": "00:00:38.5251798", "lastJackpotInstanceId": 1556359 } ] ``` Notes: - `FromDate` is required; `ToDate` defaults to now. `LevelIndexes` and `ProgressiveIds` (repeatable) narrow the levels. - `avgWinTimeSeconds` is a TimeSpan string, e.g. `"02:14:07"`. - Not deployed yet — returns `404` on Staging and Production today. Integrate against the game-scoped `/api/v3/WinHistory/summary`, which returns the same shape. Paid out in the last 24h: ```typescript const to = new Date(); const from = new Date(to.getTime() - 24 * 60 * 60 * 1000); const response = await fetch( `{{WINHISTORY_API}}/api/v3/WinHistory/product/${productId}/summary` + `?CurrencyIsoCode=EUR&FromDate=${from.toISOString()}&ToDate=${to.toISOString()}`, ); const rows = await response.json(); const paidOutCents = rows.reduce((sum, r) => sum + r.totalWinAmountCents, 0); const winCount = rows.reduce((sum, r) => sum + r.triggerCount, 0); ``` --- # FUTURE edition — API reference The full surface, including game-scoped originals, lobby opt-in (specified, not built) and server-side opt-in wagering. ## Gameplay API Game-server-facing gameplay: contributions, trigger evaluation and win lifecycle. Versions: v1, v2, v3. Host token: `{{GAMEPLAY_API}}`. ### `GET /prePlay` (v1) Retrieves pre-play information for a given request, including trigger probabilities and game level details. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `ModuleId` | query | integer | no | The ID of the module. | | `ClientId` | query | integer | no | The ID of the client. | | `ProductId` | query | integer | no | The ID of the product. | | `PlayerCurrencyIsoCode` | query | string | no | The ISO code of the player's currency. | | `api-version` | header | string | yes | | Responses: - `200` — `PrePlayResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `422` — `ValidationProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error - `503` — `ProblemDetails` — Service Unavailable ### `POST /play/calculateContribution` (v1) Calculates the contribution of a play to the jackpot based on the provided request details, including wagers, game payout, and player information. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `api-version` | header | string | yes | | Request body: `PlayContributionRequest` (see Schemas). Responses: - `200` — `PlayResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `422` — `ValidationProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error - `503` — `ProblemDetails` — Service Unavailable ### `POST /play` (v1) Processes a play request by calculating the contribution to the jackpot based on the provided play details and current game levels. This method applies various validation filters to ensure the integrity of the request and the health of the system before executing the play logic through the mediator. The response includes detailed information about the play outcome, including any contributions to the jackpot levels. This endpoint is designed to handle complex play scenarios while maintaining performance and reliability. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `api-version` | header | string | yes | | Request body: `PlayRequest` (see Schemas). Responses: - `200` — `PlayResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `422` — `ValidationProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error - `503` — `ProblemDetails` — Service Unavailable ### `PUT /winStatus` (v1) Updates the win status of a play based on the provided request details, including the outcome of the play and any relevant win information. Confirms that a jackpot win has been paid out to the player — part of the post-win lifecycle. Only available on V1/V2 (V3 batch play has no `/winStatus` endpoint). | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `api-version` | header | string | yes | | Request body: `WinStatusRequest` (see Schemas). Responses: - `202` — Accepted - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `422` — `ValidationProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error - `503` — `ProblemDetails` — Service Unavailable Notes: - Send `WinStatus = Complete` together with the original `gameTransactionIdentifier` from the winning `/play` call. ### `GET /productConfig` (v1) Retrieves product configuration information based on optional filters. If no filters are provided, returns all combinations of ModuleId, ClientId, and ProductId. If filters are provided, returns the relevant combinations based on the provided ModuleId, ClientId, and ProductId. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `ModuleId` | query | integer | no | The module ID. | | `ClientId` | query | integer | no | The client ID. | | `ProductId` | query | integer | no | The product ID. | | `api-version` | header | string | yes | | Responses: - `200` — OK - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `500` — `ProblemDetails` — Internal Server Error ### `GET /productConfig` (v2) Retrieves product configuration grouped by wager type combination. If no filters are provided, all groups are returned. Filters narrow the result to the specified module, client, and/or product, trimming each group's config tree accordingly. Groups with no matching entries after filtering are excluded from the response. The `config` field on each group is a nested object that encodes the Module → Client → [ProductId] tree: the outer keys are module IDs, the inner keys are client IDs, and each leaf array holds the product IDs that belong to that module/client. All IDs are integers; JSON requires object keys to be strings, so the IDs appear quoted on the wire but should be parsed as integers. Example response: ```[ { "jackpotTypes": ["StandardProgressive"], "wagerTypes": ["BaseBet", "SideBet"], "config": { "1": { "10": [100, 101], "11": [102] }, "2": { "20": [200] } } } ]``` The example above means module `1` has client `10` with products `100, 101` and client `11` with product `102`; module `2` has client `20` with product `200`. All listed products share the same jackpot type set (`StandardProgressive`) and wager type set (`BaseBet, SideBet`). Returns which ModuleId/ClientId/ProductId combinations are jackpot-enabled, grouped by shared jackpot and wager types to reduce payload size. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `ModuleId` | query | integer | no | The module ID. Required when int? ProductConfigRequest.ClientId or int? ProductConfigRequest.ProductId are specified. | | `ClientId` | query | integer | no | The client ID. Required when int? ProductConfigRequest.ProductId is specified. | | `ProductId` | query | integer | no | The product ID. | | `api-version` | header | string | yes | | | `If-None-Match` | header | string | no | ETag value from a previous response. Returns 304 Not Modified if the content has not changed. | Responses: - `200` — `WagerTypeCombinationGroup[]` — OK - `304` — Not Modified - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `500` — `ProblemDetails` — Internal Server Error Notes: - Supports conditional GET via `If-None-Match`/`ETag` — cache the ETag from a `200` response and revalidate on the next request; a matching ETag returns `304 Not Modified` with an empty body. ### `GET /prePlay` (v2) Retrieves pre-play information for a given request, including trigger probabilities and game level details. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `ModuleId` | query | integer | no | The ID of the module. | | `ClientId` | query | integer | no | The ID of the client. | | `ProductId` | query | integer | no | The ID of the product. | | `PlayerCurrencyIsoCode` | query | string | no | The ISO code of the player's currency. | | `api-version` | header | string | yes | | Responses: - `200` — `PrePlayResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `422` — `ValidationProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error - `503` — `ProblemDetails` — Service Unavailable ### `POST /play/calculateContribution` (v2) Calculates the contribution for a player based on the provided request and current game levels in version 2.0 of the API. This method is versioned as 2.0 and applies multiple validation and health filters before processing the request. It is intended for use in scenarios where contribution calculations must reflect current game state and player context. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `api-version` | header | string | yes | | Request body: `PlayContributionRequestV2` (see Schemas). Responses: - `200` — `PlayResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `422` — `ValidationProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error - `503` — `ProblemDetails` — Service Unavailable ### `POST /play` (v2) Processes a play request by calculating the contribution to the jackpot based on the provided play details and current game levels. This method applies various validation filters to ensure the integrity of the request and the health of the system before executing the play logic through the mediator. The response includes detailed information about the play outcome, including any contributions to the jackpot levels. This endpoint is designed to handle complex play scenarios while maintaining performance and reliability. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `api-version` | header | string | yes | | Request body: `PlayRequest` (see Schemas). Responses: - `200` — `PlayResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `422` — `ValidationProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error - `503` — `ProblemDetails` — Service Unavailable ### `PUT /winStatus` (v2) Updates the win status of a play based on the provided request details, including the outcome of the play and any relevant win information. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `api-version` | header | string | yes | | Request body: `WinStatusRequest` (see Schemas). Responses: - `202` — Accepted - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `422` — `ValidationProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error - `503` — `ProblemDetails` — Service Unavailable ### `GET /prePlay` (v3) Handles the pre-play request for jackpot levels. Fetches jackpot level configuration, exchange rates, and trigger data for a game and player before the first spin. V3 accepts multiple player currencies in a single request (V1/V2 accept one currency per call). | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `ModuleId` | query | integer | no | The ID of the module. | | `ClientId` | query | integer | no | The ID of the client. | | `ProductId` | query | integer | no | The ID of the product. | | `PlayerCurrencyIsoCode` | query | string[] | no | The ISO codes of the player's currencies. | | `api-version` | header | string | yes | | Responses: - `200` — `PrePlayResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `422` — `ValidationProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error - `503` — `ProblemDetails` — Service Unavailable Notes: - Query parameters: `ModuleId`, `ClientId`, `ProductId`, `PlayerCurrencyIsoCode` (V3 accepts this as an array; V1/V2 use a single ISO 4217 string). - Send `api-version: 3.0`. ### `POST /play/calculateContribution` (v3) Returns a list of play contribution results for the provided bets. Calculates jackpot contribution amounts for a set of bets without evaluating triggers or publishing events. Read-only — used for the first balance call before a spin is committed. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `api-version` | header | string | yes | | Request body: `PlayContributionRequest` (see Schemas). Responses: - `200` — `PlayContributionResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `422` — `ValidationProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error - `503` — `ProblemDetails` — Service Unavailable ### `POST /play` (v3) Handles the play request for jackpot levels. The transactional core of the Gameplay API — submits one or more wagers, contributes to jackpot pools, evaluates triggers, and returns win information. V3 processes a batch of player bets (a "bet group") in a single request. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `api-version` | header | string | yes | | Request body: `PlayRequest` (see Schemas). Responses: - `200` — `PlayResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `422` — `ValidationProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error - `503` — `ProblemDetails` — Service Unavailable Notes: - A `422` response means the bet was invalid — the calling game server MUST roll back the spin. - Idempotent via `gameTransactionIdentifier` on each bet: retrying the same identifier does not double-contribute or double-trigger. TypeScript: ```typescript const response = await fetch(`{{GAMEPLAY_API}}/play`, { method: "POST", headers: { Authorization: `Bearer ${accessToken}`, "api-version": "3.0", "Content-Type": "application/json", }, body: JSON.stringify({ betGroupId: "group-123", betGroupSessionId: "session-456", betGroupTransactionId: crypto.randomUUID(), bets: [ { wagers: [{ wagerAmountInCents: 500, wagerType: "BaseBet" }], gamePayout: 0, betTimestamp: new Date().toISOString(), moduleId: 1, clientId: 2, productId: 3, playerId: "player-1", playerSessionId: "session-1", playerCurrencyIsoCode: "EUR", spinType: "Normal", gameTransactionIdentifier: crypto.randomUUID(), transactionNumber: 1001, eventId: 5001, }, ], }), }); if (response.status === 422) { // Invalid bet — roll back the spin. } ``` C#: ```csharp var request = new PlayRequest { BetGroupId = "group-123", BetGroupSessionId = "session-456", BetGroupTransactionId = Guid.NewGuid(), Bets = [ new PlayBetRequest { Wagers = [new WagerRequest { WagerAmountInCents = 500, WagerType = EWagerType.BaseBet }], GamePayout = 0, BetTimestamp = DateTimeOffset.UtcNow, ModuleId = 1, ClientId = 2, ProductId = 3, PlayerId = "player-1", PlayerSessionId = "session-1", PlayerCurrencyIsoCode = "EUR", SpinType = "Normal", GameTransactionIdentifier = Guid.NewGuid(), TransactionNumber = 1001, EventId = 5001, }, ], }; using var httpRequest = new HttpRequestMessage(HttpMethod.Post, "/play") { Content = JsonContent.Create(request), }; httpRequest.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken); httpRequest.Headers.Add("api-version", "3.0"); var response = await httpClient.SendAsync(httpRequest); // response.StatusCode == 422 => roll back the spin. ``` ### Gameplay API — schemas #### `EJackpotType` _No fields._ #### `EMultiplierType` _No fields._ #### `EWagerType` _No fields._ #### `EWinStatus` _No fields._ #### `FeesInPlayerCurrencyResponse` Represents the fee information for a specific jackpot level within a play session. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `adminFeeInCents` | number | yes | The administrative fee, in cents. | | `marketingFeeInCents` | number | yes | The marketing fee, in cents. | #### `PlayContributionRequest` Represents a request to calculate contribution, including wager details, player information, and game context. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `bets` | BetRequest[] (see `BetRequest`) | yes | The collection of bets to calculate contributions for. | #### `PlayJackpotLevel` Represents detailed information about a specific jackpot level within a play response, including identifiers, contribution amounts, currency, and optional win details. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `jackpotLevelIndex` | integer | yes | The index of the jackpot level. | | `jackpotLevelId` | string | yes | The unique identifier for the jackpot level. | | `jackpotLevelName` | string | yes | The name of the jackpot level. | | `jackpotSeriesName` | string | yes | The name of the jackpot series. | | `progressiveId` | integer | yes | The unique ID that identifies a jackpot level. | | `jackpotCurrencyIsoCode` | string | yes | The ISO code of the jackpot currency. | | `bets` | BetInformation[] (see `BetInformation`) | yes | The contribution and win information for each individual bet. | | `winInformation` | object | yes | | #### `PlayRequest` Represents a V3 play request for a bet group containing one or more bets. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `betGroupId` | string | yes | The ID of the bet group. | | `betGroupSessionId` | string | yes | The session ID of the bet group. | | `betGroupTransactionId` | object | yes | The transaction ID of the bet group as a Guid. | | `bets` | PlayBetRequest[] (see `PlayBetRequest`) | yes | The list of bets within the bet group. | | `winInformation` | object | yes | | #### `PlayResponse` Represents the response for a play request, including the jackpot levels and their associated information. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `levels` | PlayJackpotLevel[] (see `PlayJackpotLevel`) | yes | The list of jackpot levels. | #### `PrePlayJackpotLevel` Represents detailed information about a specific jackpot level within a pre-play session. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `jackpotLevelIndex` | integer | yes | The index of the jackpot level. | | `jackpotLevelId` | string | yes | The unique identifier for the jackpot level. | | `jackpotLevelName` | string | yes | The name of the jackpot level. | | `jackpotSeriesName` | string | yes | The name of the jackpot series. | | `progressiveId` | integer | yes | The unique ID that identifies a jackpot level. | | `jackpotCurrencyIsoCode` | string | yes | The ISO code of the jackpot currency. | | `jackpotToPlayerExchangeRate` | Record | yes | The exchange rate from the jackpot currency to the player's currency. | | `jackpotType` | EJackpotType (see `EJackpotType`) | yes | The type of the jackpot. | | `standardProgressive` | object | yes | | | `valueBasedMysteryMustBeWon` | object | yes | | | `valueBasedMysteryRandom` | object | yes | | | `rtp` | number | yes | The return to player (RTP) value. | | `exchangeRateMultiplierType` | EMultiplierType (see `EMultiplierType`) | yes | The type of the exchange rate multiplier. | #### `PrePlayResponse` Represents the response for a pre-play request, including the jackpot levels involved. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `levels` | PrePlayJackpotLevel[] (see `PrePlayJackpotLevel`) | yes | The list of jackpot levels. | | `gameServiceProperties` | Record | no | Gets the game service properties associated with the pre-play response.; nullable | #### `ProblemDetails` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `type` | string | no | nullable | | `title` | string | no | nullable | | `status` | integer | no | nullable | | `detail` | string | no | nullable | | `instance` | string | no | nullable | #### `StandardProgressiveProperties` Represents the properties for a standard progressive jackpot. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `triggerProbability` | TriggerProbability (see `TriggerProbability`) | yes | The probability of triggering the jackpot. | #### `TriggerProbability` Represents the trigger probability for a jackpot level, including probabilities per wager and per spin at maximum bet, as well as wager type probabilities. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `probabilityPerWagerAtMaxBet` | number | yes | The probability per wager based on the amount defined in MaxBetInCents. | | `probabilityPerSpinAtMaxBet` | number | yes | The probability per spin based on the amount defined in MaxBetInCents. | | `maxBetInCents` | integer | yes | The bet amount in cents of which the trigger probabilities are based on. | | `wagerTypeProbabilities` | Record (see `WagerTypeTriggerProbability`) | no | A dictionary containing probabilities for each wager type.; nullable | #### `ValidationProblemDetails` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `type` | string | no | nullable | | `title` | string | no | nullable | | `status` | integer | no | nullable | | `detail` | string | no | nullable | | `instance` | string | no | nullable | | `errors` | Record | no | | #### `ValueBasedMysteryMustBeWonProperties` Represents the properties for a value-based mystery must be won jackpot. _No fields._ #### `ValueBasedMysteryRandomProperties` Represents the properties for a value-based mystery random jackpot. _No fields._ #### `WagerRequest` Represents a wager within a bet. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `wagerAmountInCents` | integer | yes | The amount of the wager in cents. | | `wagerType` | EWagerType (see `EWagerType`) | yes | The type of the wager. | #### `WagerTypeTriggerProbability` Represents the trigger probability for a specific wager type. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `probabilityPerWagerAtMaxBet` | number | yes | The probability per wager based on the amount defined in MaxBetInCents. | | `probabilityPerSpinAtMaxBet` | number | yes | The probability per spin based on the amount defined in MaxBetInCents. | #### `WinInformationRequest` Win Information for the V3 Play Request. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `jackpotLevelIndex` | integer | yes | Field is nullable so if not provided, the [Required] attribute will fail. If the field is byte, and no value is provided in the json, it would assume 0; nullable | | `triggerProbability` | TriggerProbability (see `TriggerProbability`) | yes | The probability of triggering the jackpot. | | `jackpotToPlayerExchangeRate` | Record | yes | A dictionary of exchange rates to convert jackpot amounts to player currency. | #### `WinInformationResponse` Represents the win information for a specific jackpot level within a play session. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `jackpotInstanceId` | integer | yes | The unique identifier for the jackpot instance. | | `jackpotNumber` | integer | yes | The number of the jackpot. | | `playerWinAmountInCents` | integer | yes | The amount won by the player, in cents. | | `newJackpotAmountInCents` | integer | yes | The new amount of the jackpot, in cents. | #### `WinStatusRequest` Represents a request for win status. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `status` | EWinStatus (see `EWinStatus`) | yes | The status of the win. | | `moduleId` | integer | yes | The ID of the module. | | `clientId` | integer | yes | The ID of the client. | | `productId` | integer | yes | The ID of the product. | | `playerId` | string | yes | The ID of the player. | | `playerSessionId` | string | yes | The session ID of the player. | | `playerCurrencyIsoCode` | string | yes | The ISO code of the player's currency. | | `gameTransactionIdentifier` | string (uuid) | yes | The identifier for the game transaction. | | `transactionNumber` | integer | yes | The number of the transaction. | | `eventId` | integer | yes | The ID of the event. | | `winInformation` | WinStatusWinInformationRequest (see `WinStatusWinInformationRequest`) | yes | The win information. | #### `WinStatusWinInformationRequest` Win Information for the Win Status Request | Field | Type | Required | Notes | | --- | --- | --- | --- | | `jackpotLevelIndex` | integer | yes | Field is nullable so if not provided, the [Required] attribute will fail. If the field is byte, and no value is provided in the json, it would assume 0; nullable | | `jackpotInstanceId` | integer | yes | The triggered Jackpot Instance Id | | `playerWinPaidAmountInCents` | integer | yes | The actual amount paid out to the user | #### `PlayContributionRequestV2` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `wagers` | WagerRequest[] (see `WagerRequest`) | yes | | | `betTimestamp` | string (date-time) | yes | | | `gamePayout` | integer | yes | | | `moduleId` | integer | yes | | | `clientId` | integer | yes | | | `productId` | integer | yes | | | `playerId` | string | yes | | | `playerCurrencyIsoCode` | string | yes | | | `spinType` | string | yes | | #### `WagerTypeCombinationGroup` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `jackpotTypes` | EJackpotType[] (see `EJackpotType`) | yes | | | `wagerTypes` | EWagerType[] (see `EWagerType`) | yes | | | `config` | Record> | yes | | #### `BetContributionInformation` Represents contribution and win information for an individual bet within a jackpot level. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `moduleId` | integer | yes | The ID of the module. | | `clientId` | integer | yes | The ID of the client. | | `productId` | integer | yes | The ID of the product. | | `playerId` | string | yes | The ID of the player. | | `contributionAmountInCents` | ContributionAmountInCents[] (see `ContributionAmountInCents`) | yes | The per-wager-type contribution amounts in both jackpot and player currencies. Only wager types with a non-zero contribution are included. | | `feesInPlayerCurrency` | object | yes | | #### `BetInformation` Represents contribution and win information for an individual bet within a jackpot level. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `moduleId` | integer | yes | The ID of the module. | | `clientId` | integer | yes | The ID of the client. | | `productId` | integer | yes | The ID of the product. | | `playerId` | string | yes | The ID of the player. | | `contributionAmountInCents` | ContributionAmountInCents[] (see `ContributionAmountInCents`) | yes | The per-wager-type contribution amounts in both jackpot and player currencies. Only wager types with a non-zero contribution are included. | | `feesInPlayerCurrency` | object | yes | | | `winInformation` | object | yes | | #### `BetRequest` Represents a request to place a bet, including wager details, player information, and game context. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `wagers` | WagerRequest[] (see `WagerRequest`) | yes | The collection of wager requests to be included in the bet. Must contain at least one wager. | | `betTimestamp` | string (date-time) | yes | The timestamp indicating when the bet was placed. Must not be empty. | | `gamePayout` | integer | yes | The total payout amount for the game, in the smallest currency unit. Must be zero or a positive value. | | `moduleId` | integer | yes | The identifier of the game module associated with the bet. Must be a positive integer. | | `clientId` | integer | yes | The identifier of the client placing the bet. Must be a positive integer. | | `productId` | integer | yes | The identifier of the product for which the bet is placed. Must be a positive integer. | | `playerId` | string | yes | The unique identifier of the player placing the bet. Must not be null or empty. | | `playerCurrencyIsoCode` | string | yes | The ISO 4217 currency code representing the player's currency. Must be exactly three characters. | | `spinType` | string | yes | The type of spin or game action being performed. Must be a valid spin type string. | #### `BetWinInformation` Represents the win information for a bet, including the player's win amount and the new jackpot amount. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `playerWinAmountInCents` | integer | yes | The amount won by the player, in cents. | | `newJackpotAmountInCents` | integer | yes | The new amount of the jackpot, in cents. | #### `ContributionAmountInCents` Represents the contribution amount for a single wager type, expressed in both the jackpot currency and the player currency. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `wagerType` | EWagerType (see `EWagerType`) | yes | The wager type. | | `inJackpotCurrency` | number | yes | The contribution amount in cents in the jackpot currency. | | `inPlayerCurrency` | number | yes | The contribution amount in cents in the player currency. | #### `FeesInPlayerCurrency` Represents the fees associated with a bet, including administrative and marketing fees. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `adminFeeInCents` | number | yes | The administrative fee, in cents. | | `marketingFeeInCents` | number | yes | The marketing fee, in cents. | #### `LevelWinInformation` Represents the win information for a jackpot level, including the jackpot instance and its number. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `jackpotInstanceId` | integer | yes | The unique identifier for the jackpot instance. | | `jackpotNumber` | integer | yes | The number of the jackpot. | #### `PlayBetRequest` Represents an individual bet within a bet group. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `wagers` | WagerRequest[] (see `WagerRequest`) | yes | The list of wagers within the bet. | | `gamePayout` | integer | yes | The payout amount for the game. | | `betTimestamp` | string (date-time) | yes | The timestamp of the bet. | | `moduleId` | integer | yes | The ID of the module. | | `clientId` | integer | yes | The ID of the client. | | `productId` | integer | yes | The ID of the product. | | `playerId` | string | yes | The ID of the player. | | `playerSessionId` | string | yes | The session ID of the player. | | `spinType` | string | yes | The type of the spin. | | `gameTransactionIdentifier` | object | yes | The identifier for the game transaction. | | `transactionNumber` | integer | yes | The number of the transaction. | | `eventId` | integer | yes | The ID of the event. | | `additionalJackpotPayload` | string | no | Optional additional payload for the jackpot.; nullable | | `playerCurrencyIsoCode` | string | yes | A 3-letter ISO currency code for the player. | #### `PlayContributionJackpotLevel` Represents detailed information about a specific jackpot level within a play response, including identifiers, contribution amounts, currency, and optional win details. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `jackpotLevelIndex` | integer | yes | The index of the jackpot level. | | `jackpotLevelId` | string | yes | The unique identifier for the jackpot level. | | `jackpotLevelName` | string | yes | The name of the jackpot level. | | `jackpotSeriesName` | string | yes | The name of the jackpot series. | | `progressiveId` | integer | yes | The unique ID that identifies a jackpot level. | | `jackpotCurrencyIsoCode` | string | yes | The ISO code of the jackpot currency. | | `betContributions` | BetContributionInformation[] (see `BetContributionInformation`) | yes | The contribution and win information for each individual bet. | #### `PlayContributionResponse` Represents the response for a play request, including the jackpot levels and their associated information. | Field | Type | Required | Notes | | --- | --- | --- | --- | | `levels` | PlayContributionJackpotLevel[] (see `PlayContributionJackpotLevel`) | yes | The list of jackpot levels. | ## Ticker API Lobby- and game-facing jackpot values, settings and the /tickerHub SignalR hub. Versions: v1, v2. Host token: `{{TICKER_API}}`. ### `GET /v1/Settings` (v1) Handles settings requests. Betsettings and winhistory settings (if available) are returned based on the provided product, game client, game module and currency. V1 ticker display settings (colors, formatting) for a product/module/client combination. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `productId` | query | integer | yes | | | `gameClientId` | query | integer | yes | | | `gameModuleId` | query | integer | yes | | | `currencyIsoCode` | query | string | yes | | Responses: - `200` — `SettingsResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `422` — `ProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error ### `GET /v1/ticker` (v1) Handles GET requests for ticker data. V1 lobby ticker endpoint — a different response shape to v2's `/counters` (series and level information for one game), superseded by `GET /v2/counters` for new integrations. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `productId` | query | integer | yes | | | `gameClientId` | query | integer | yes | | | `gameModuleId` | query | integer | yes | | | `currencyIsoCode` | query | string | yes | | Responses: - `200` — `TickerResponse` — OK - `400` — `ProblemDetails` — Bad Request - `500` — `ErrorResponseOfError` — Internal Server Error ### `GET /v2/counters` (v2) Handles GET requests for lobby tickers. The lobby ticker list — jackpot level values for display in the lobby. `counters` exists on v2 only: `GET /v1/counters` returns `404`, and v1's equivalent is the differently-shaped `GET /v1/ticker`. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `productId` | query | integer | no | | | `moduleId` | query | integer | no | | | `currencyIsoCode` | query | string | yes | | Responses: - `200` — `LobbyTickerResponse[]` — OK - `400` — `ProblemDetails` — Bad Request - `500` — `ErrorResponseOfError` — Internal Server Error `200` response (real production body): ```json [ { "progressiveId": 20153, "productId": 16755, "moduleId": 18661, "gamePayId": 0, "startAtValue": 18805.84, "endAtValue": 18812.85, "numberOfSeconds": 600, "centsPerSecond": 1, "currencyIsoCode": "EUR", "friendlyName": "9 Masks of Fire v94", "jackpotNumber": 23, "triggerCount": 22, "secondsSinceLastWin": 103199, "rtp": 5, "jackpotName": "MADNESS", "jackpotType": 3, "jackpotMaxAmountCents": 1169066464783, "rtpPercentages": { "OptIn": 5 } }, { "progressiveId": 20154, "productId": 16755, "moduleId": 18661, "gamePayId": 1, "startAtValue": 164.80, "endAtValue": 171.81, "numberOfSeconds": 600, "centsPerSecond": 1, "currencyIsoCode": "EUR", "friendlyName": "9 Masks of Fire v94", "jackpotNumber": 8864, "triggerCount": 8863, "secondsSinceLastWin": 754, "rtp": 10, "jackpotName": "MAYHEM", "jackpotType": 2, "jackpotMaxAmountCents": 23381, "rtpPercentages": { "OptIn": 10 } } ] ``` Notes: - `currencyIsoCode` is required. Pass `productId` and `moduleId` together to scope a lobby to one product and game — a module alone returns every link group it touches, repeated per game sharing each pool. - `startAtValue` and `endAtValue` are currency units (e.g. `13842.74` EUR), not cents — only `centsPerSecond` is cents. `endAtValue` is the next animation checkpoint, never a ceiling. - Animate client-side from `startAtValue` to `endAtValue` at `centsPerSecond` rather than polling for every intermediate value — `/v2/counters` is output-cached for 2s server-side. Fetch lobby counters: ```typescript const response = await fetch( `{{TICKER_API}}/v2/counters?productId=${productId}&moduleId=${moduleId}¤cyIsoCode=EUR`, ); const counters = await response.json(); // Animate each counter from startAtValue to endAtValue at centsPerSecond client-side. ``` ### `GET /v2/Settings` (v2) Returns Settings Requests such as bet settings and/or win-history settings based on the provided product, game client, game module and currency. V2 ticker display settings (colors, formatting) for a product/module/client combination. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `productId` | query | integer | yes | | | `gameClientId` | query | integer | yes | | | `gameModuleId` | query | integer | yes | | | `currencyIsoCode` | query | string | yes | | Responses: - `200` — `SettingsResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `422` — `ProblemDetails` — Unprocessable Entity - `500` — `ProblemDetails` — Internal Server Error ### Ticker API — schemas #### `BaseWinHistorySettingResponse` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `enabled` | boolean | yes | | | `minThreshold` | integer | no | nullable | | `value` | integer | no | nullable | #### `EJackpotType` _No fields._ #### `Error` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `application` | string | yes | | | `message` | string | yes | | | `description` | string | yes | | #### `ErrorResponseOfError` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `errors` | Error[] (see `Error`) | no | | #### `LevelConfig` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `name` | string | no | | | `jackpotType` | EJackpotType (see `EJackpotType`) | no | | | `jackpotStartAmountCents` | number | no | | | `jackpotMaxAmountCents` | number | no | | | `coinSize` | integer | no | nullable | | `triggerBetLimit` | integer | no | nullable | | `rtpPercentage` | number | no | nullable | | `rtpPercentages` | Record | no | | | `isVisible` | boolean | no | | #### `LevelInfo` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `levelNumber` | integer | no | | | `jackpotNumber` | integer | no | | | `triggerCount` | integer | no | | | `startAmount` | number | no | | | `endAmount` | number | no | | | `hotnessPercentage` | number | no | | | `progressiveId` | integer | no | | | `levelConfiguration` | LevelConfig (see `LevelConfig`) | no | | #### `ProblemDetails` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `type` | string | no | nullable | | `title` | string | no | nullable | | `status` | integer | no | nullable | | `detail` | string | no | nullable | | `instance` | string | no | nullable | #### `SettingsResponse` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `betSettings` | object | no | | | `winHistorySettings` | object | no | | #### `ThemeInfo` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `effectiveFrom` | string (date-time) | yes | nullable | | `effectiveTo` | string (date-time) | yes | nullable | | `guid` | string (uuid) | yes | | #### `TickerResponse` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `productExternalId` | integer | yes | nullable | | `gameClientExternalId` | integer | yes | nullable | | `gameModuleExternalId` | integer | yes | nullable | | `seriesName` | string | yes | | | `numberOfLevels` | integer | no | | | `currencyIsoCode` | string | yes | | | `multiplierType` | string | yes | | | `tickPeriod` | integer | yes | | | `pollPeriod` | integer | yes | | | `isAllowGamePlay` | boolean | yes | | | `levelInformation` | LevelInfo[] (see `LevelInfo`) | yes | | | `winInformation` | WinInfo[] (see `WinInfo`) | yes | | | `themeInformation` | ThemeInfo[] (see `ThemeInfo`) | yes | | #### `ValidationProblemDetails` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `type` | string | no | nullable | | `title` | string | no | nullable | | `status` | integer | no | nullable | | `detail` | string | no | nullable | | `instance` | string | no | nullable | | `errors` | Record | no | | #### `WinHistorySettingsResponse` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `winAmount` | BaseWinHistorySettingResponse (see `BaseWinHistorySettingResponse`) | yes | | | `winCount` | BaseWinHistorySettingResponse (see `BaseWinHistorySettingResponse`) | yes | | #### `WinInfo` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `jackpotType` | EJackpotType (see `EJackpotType`) | no | | | `levelNumber` | integer | no | | | `winAmount` | number | no | | | `playerId` | integer | no | | | `userPlayerId` | string | no | | | `productId` | integer | no | | | `jackpotNumber` | integer | no | | | `jackpotTriggerTime` | string (date-time) | no | | #### `BetSettingsResponse` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `betValuesCents` | integer[] | yes | | | `mostPopularBetValueCents` | integer | yes | nullable | #### `LobbyTickerResponse` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `progressiveId` | integer | no | | | `productId` | integer | no | nullable | | `moduleId` | integer | no | nullable | | `gamePayId` | integer | no | | | `startAtValue` | number | no | | | `endAtValue` | number | no | | | `numberOfSeconds` | number | no | | | `centsPerSecond` | integer | no | nullable | | `currencyIsoCode` | string | yes | | | `friendlyName` | string | yes | | | `jackpotNumber` | integer | no | nullable | | `triggerCount` | integer | no | | | `secondsSinceLastWin` | integer | no | nullable | | `rtp` | number | no | nullable | | `jackpotName` | string | yes | | | `jackpotType` | EJackpotType (see `EJackpotType`) | no | | | `jackpotMaxAmountCents` | number | no | | | `rtpPercentages` | Record | no | | ## Win History API Recent wins, summaries and play-check for lobbies and players. Versions: v2, v3. Host token: `{{WINHISTORY_API}}`. ### `GET /v2/PlayCheck` (v2) Checks the winning Transaction for a given user and game transaction number. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `UserId` | query | string | no | User Id associated with the game transaction to be checked for winning status. | | `GameTransactionNumber` | query | integer | no | Game transaction number to be checked for winning status. This should be a unique identifier for the specific game play transaction. | Responses: - `200` ### `GET /api/WinHistory/v2/progressive/wins/{moduleId}/recent/{currencyIsoCode}/{limit}` (v2) Handles the request to get recent progressive wins v2. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `Limit` | path | integer | yes | The number of wins per jackpot to return, starting with the most recent; min 1; max 100 | | `ModuleId` | path | integer | yes | min 1; max 2147483647 | | `CurrencyIsoCode` | path | string | yes | pattern `^[A-Za-z]{3}$` | | `progressiveId` | query | integer[] | no | | | `gamePayId` | query | integer[] | no | | | `ProductId` | query | integer | no | min 1; max 2147483647 | | `JackpotLinkGroupId` | query | integer | no | min 1; max 2147483647 | Responses: - `200` — List of recent progressive wins. ### `GET /api/WinHistory/v2/progressive/wins/{moduleId}/summary/{currencyIsoCode}/{period}` (v2) Handles the request to get summary of progressive wins v2. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `ModuleId` | path | integer | yes | min 1; max 2147483647 | | `CurrencyIsoCode` | path | string | yes | pattern `^[A-Za-z]{3}$` | | `progressiveId` | query | integer[] | no | | | `gamePayId` | query | integer[] | no | | | `ProductId` | query | integer | no | min 1; max 2147483647 | | `JackpotLinkGroupId` | query | integer | no | min 1; max 2147483647 | | `period` | path | string | yes | There values that follow a dynamic syntax:
  • last_{N}_days (ex.: last_18_days)
  • last_{N}_months (ex.: last_6_months)
; one of: all, today, yesterday, month_to_date, quarter_to_date, year_to_date, this_day, this_week, this_month, this_quarter, this_year, last_day, last_week, last_month, last_quarter, last_year, last_N_days, last_N_months | Responses: - `200` — List of summary of progressive wins. ### `GET /api/v3/WinHistory/recent` (v3) Handles the request to get recent wins v3. The most recent jackpot wins for a game, newest first — live in production today, and what a lobby's recent-winners strip calls until the product-scoped route deploys. The brief refers to this endpoint as `/api/v3/winhistory/recent` (lowercase); the generated key preserves the OpenAPI spec's casing (`WinHistory`), so this overlay attaches to that key. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `LevelIndexes` | query | integer[] | no | List of level index to return win values. | | `Count` | query | integer | no | Count of records to be returned. Default: 100. Limit: 100.; min 1; max 100 | | `ModuleId` | query | integer | no | min 1; max 2147483647 | | `ClientId` | query | integer | no | min 1; max 2147483647 | | `ProductId` | query | integer | no | min 1; max 2147483647 | | `CurrencyIsoCode` | query | string | no | pattern `^[A-Za-z]{3}$` | Responses: - `200` `200` response (real production body): ```json [ { "winDateTime": "2026-09-15T13:09:50.2736061+02:00", "winAmountCents": 2338, "jackpotInstanceId": 1557771, "progressiveId": 20156, "levelIndex": 3, "triggerCount": 96063 }, { "winDateTime": "2026-09-15T13:09:39.9550911+02:00", "winAmountCents": 1753, "jackpotInstanceId": 1557770, "progressiveId": 20157, "levelIndex": 4, "triggerCount": 213404 } ] ``` Notes: - `ModuleId`, `ClientId` and `ProductId` are all required in practice — the spec marks them optional, but the service returns `400` ("ClientId must be a positive number") when any one is missing. - `Count` ranges from 1–100 (default 100); `LevelIndexes` (repeatable) narrows to specific levels — unfiltered, frequent levels swamp rare ones. - Output-cached for 300s with a 120s invalidation delay — a fresh win can take a couple of minutes to appear. - `progressiveId` is composed from the site id and the level id, so it equals the raw level id `/v2/counters` emits only while the site id is zero — which is what production returns for the live series today (verified 2026-09-15). Match wins to levels by `levelIndex` (the ticker's `gamePayId`) rather than joining on `progressiveId`. Fetch recent wins: ```typescript const response = await fetch( `{{WINHISTORY_API}}/api/v3/WinHistory/recent` + `?ModuleId=${moduleId}&ClientId=${clientId}&ProductId=${productId}&CurrencyIsoCode=EUR&Count=20`, ); const recentWins = await response.json(); ``` ### `GET /api/v3/WinHistory/product/{productId}/recent` (v3) Handles the request to get recent wins across every jackpot a product contributes to, without naming a game. Recent wins across every jackpot a product contributes to, without naming a game — the lobby's recent-winners feed. The product is a path segment; everything else is query. A jackpot reachable through more than one link group is counted once. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `ProductId` | path | integer | yes | The product/brand to return wins for.; min 1; max 2147483647 | | `CurrencyIsoCode` | query | string | no | The currency code to return the win values in. The code is in ISO 4217 format.; pattern `^[A-Za-z]{3}$` | | `LevelIndexes` | query | integer[] | no | List of level index to return win values. | | `ProgressiveIds` | query | integer[] | no | Restricts the response to these jackpots. Ids are the `progressiveId` values the ticker's `/v2/counters` feed returns, so a lobby can pass straight through what it already holds. Omit to return every jackpot the product reaches. | | `Count` | query | integer | no | Count of records to be returned. Default: 100. Limit: 100.; min 1; max 100 | Responses: - `200` `200` response (real production body): ```json [ { "winDateTime": "2026-09-15T13:09:50.2736061+02:00", "winAmountCents": 2338, "jackpotInstanceId": 1557771, "progressiveId": 20156, "levelIndex": 3, "triggerCount": 96063 }, { "winDateTime": "2026-09-15T13:09:39.9550911+02:00", "winAmountCents": 1753, "jackpotInstanceId": 1557770, "progressiveId": 20157, "levelIndex": 4, "triggerCount": 213404 } ] ``` Notes: - `Count` ranges from 1–100 (default 100); `LevelIndexes` and `ProgressiveIds` (both repeatable) narrow to specific levels. - `progressiveId` is composed from the site id and the level id, so it equals the raw level id `/v2/counters` emits only while the site id is zero — which is what production returns for the live series today (verified 2026-09-15). Match wins to levels by `levelIndex` (the ticker's `gamePayId`) rather than joining on `progressiveId`. - Output-cached for 300s with a 120s invalidation delay — a lobby strip can be up to ~5 minutes behind. - Not deployed yet — returns `404` on Staging and Production today. Integrate against the game-scoped `/api/v3/WinHistory/recent`, which returns the same shape. Recent winners for a product: ```typescript const response = await fetch( `{{WINHISTORY_API}}/api/v3/WinHistory/product/${productId}/recent?CurrencyIsoCode=EUR&Count=10`, ); const wins = await response.json(); // [{ progressiveId, levelIndex, triggerCount, winDateTime, winAmountCents, jackpotInstanceId }] ``` ### `GET /api/v3/WinHistory/product/{productId}/summary` (v3) Handles the request to get a win summary across every jackpot a product contributes to, without naming a game. Per-level win totals for a product over a period, without naming a game — what an operator lobby leads with: the value and volume of wins paid out. One row per jackpot level; sum `totalWinAmountCents` and `triggerCount` across rows for the headline. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `ProductId` | path | integer | yes | The product/brand to return the summary for.; min 1; max 2147483647 | | `CurrencyIsoCode` | query | string | no | The currency code to return the win values in. The code is in ISO 4217 format.; pattern `^[A-Za-z]{3}$` | | `LevelIndexes` | query | integer[] | no | List of level index to return win values. | | `ProgressiveIds` | query | integer[] | no | Restricts the response to these jackpots. Ids are the `progressiveId` values the ticker's `/v2/counters` feed returns, so a lobby can pass straight through what it already holds. Omit to return every jackpot the product reaches. | | `FromDate` | query | string (date-time) | no | Starting date to fetch data from. | | `ToDate` | query | string (date-time) | no | Ending date to fetch data to. Default: Now. | Responses: - `200` `200` response (real production body): ```json [ { "progressiveId": 20156, "levelIndex": 3, "triggerCount": 1551, "triggerCountAllTime": 27758, "totalWinAmountCents": 3620563, "highestWinAmountCents": 2338, "avgWinAmountCents": 2334, "avgWinTimeSeconds": "00:01:12.6634429", "lastJackpotInstanceId": 1556367 }, { "progressiveId": 20158, "levelIndex": 5, "triggerCount": 2919, "triggerCountAllTime": 54045, "totalWinAmountCents": 3406253, "highestWinAmountCents": 1169, "avgWinAmountCents": 1166, "avgWinTimeSeconds": "00:00:38.5251798", "lastJackpotInstanceId": 1556359 } ] ``` Notes: - `FromDate` is required; `ToDate` defaults to now. `LevelIndexes` and `ProgressiveIds` (repeatable) narrow the levels. - `avgWinTimeSeconds` is a TimeSpan string, e.g. `"02:14:07"`. - Not deployed yet — returns `404` on Staging and Production today. Integrate against the game-scoped `/api/v3/WinHistory/summary`, which returns the same shape. Paid out in the last 24h: ```typescript const to = new Date(); const from = new Date(to.getTime() - 24 * 60 * 60 * 1000); const response = await fetch( `{{WINHISTORY_API}}/api/v3/WinHistory/product/${productId}/summary` + `?CurrencyIsoCode=EUR&FromDate=${from.toISOString()}&ToDate=${to.toISOString()}`, ); const rows = await response.json(); const paidOutCents = rows.reduce((sum, r) => sum + r.totalWinAmountCents, 0); const winCount = rows.reduce((sum, r) => sum + r.triggerCount, 0); ``` ### `GET /api/v3/WinHistory/product/{productId}/overview` (v3) Handles the request to get an all-time win overview across every jackpot a product contributes to, without naming a game. All-time totals per jackpot level for a product, without naming a game. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `ProductId` | path | integer | yes | The product/brand to return the overview for.; min 1; max 2147483647 | | `CurrencyIsoCode` | query | string | no | The currency code to return the win values in. The code is in ISO 4217 format.; pattern `^[A-Za-z]{3}$` | | `ProgressiveIds` | query | integer[] | no | Restricts the response to these jackpots. Ids are the `progressiveId` values the ticker's `/v2/counters` feed returns, so a lobby can pass straight through what it already holds. Omit to return every jackpot the product reaches. | Responses: - `200` `200` response (real production body): ```json [ { "progressiveId": 20155, "highestWinAmountCents": 5902, "lastWinAmountCents": 3149, "lastWinDateTime": "2026-09-15T11:14:38.1735369+02:00", "totalWinAmountCents": 223817310, "triggerCountAllTime": 52576 } ] ``` Notes: - Not deployed yet — returns `404` on Staging and Production today. Integrate against the game-scoped `/api/v3/WinHistory/overview`, which returns the same shape. ### `GET /api/v3/WinHistory/summary` (v3) Handles the request to get summary of wins v3. Per-level win totals for a game over a period — live in production today. The value and volume an operator lobby leads with: one row per jackpot level, so sum `totalWinAmountCents` and `triggerCount` across rows for the headline. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `LevelIndexes` | query | integer[] | no | List of level index to return win values. | | `FromDate` | query | string (date-time) | no | Starting date to fetch data from | | `ToDate` | query | string (date-time) | no | Ending date to fetch data to. Default: Now | | `ModuleId` | query | integer | no | min 1; max 2147483647 | | `ClientId` | query | integer | no | min 1; max 2147483647 | | `ProductId` | query | integer | no | min 1; max 2147483647 | | `CurrencyIsoCode` | query | string | no | pattern `^[A-Za-z]{3}$` | Responses: - `200` `200` response (real production body): ```json [ { "progressiveId": 20156, "levelIndex": 3, "triggerCount": 1551, "triggerCountAllTime": 27758, "totalWinAmountCents": 3620563, "highestWinAmountCents": 2338, "avgWinAmountCents": 2334, "avgWinTimeSeconds": "00:01:12.6634429", "lastJackpotInstanceId": 1556367 }, { "progressiveId": 20158, "levelIndex": 5, "triggerCount": 2919, "triggerCountAllTime": 54045, "totalWinAmountCents": 3406253, "highestWinAmountCents": 1169, "avgWinAmountCents": 1166, "avgWinTimeSeconds": "00:00:38.5251798", "lastJackpotInstanceId": 1556359 } ] ``` Notes: - `ModuleId`, `ClientId` and `ProductId` are all required in practice, as on `/recent`. - Omit `FromDate` for all-time totals; `ToDate` defaults to now. `LevelIndexes` (repeatable) narrows the levels. - Output-cached for 300s with a 120s invalidation delay — a fresh win can take a couple of minutes to appear. - `avgWinTimeSeconds` is a TimeSpan string, e.g. `"02:14:07"`. Paid out in the last 24h: ```typescript const to = new Date(); const from = new Date(to.getTime() - 24 * 60 * 60 * 1000); const response = await fetch( `{{WINHISTORY_API}}/api/v3/WinHistory/summary` + `?ModuleId=${moduleId}&ClientId=${clientId}&ProductId=${productId}&CurrencyIsoCode=EUR` + `&FromDate=${from.toISOString()}&ToDate=${to.toISOString()}`, ); const rows = await response.json(); const paidOutCents = rows.reduce((sum, r) => sum + r.totalWinAmountCents, 0); const winCount = rows.reduce((sum, r) => sum + r.triggerCount, 0); ``` ### `GET /api/v3/WinHistory/overview` (v3) Handles the request to get an overview of wins v3. All-time totals per jackpot level for a game — highest win, last win and lifetime trigger count. Live in production today; takes the same ModuleId + ClientId + ProductId triple as /recent and /summary. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `ModuleId` | query | integer | no | min 1; max 2147483647 | | `ClientId` | query | integer | no | min 1; max 2147483647 | | `ProductId` | query | integer | no | min 1; max 2147483647 | | `CurrencyIsoCode` | query | string | no | pattern `^[A-Za-z]{3}$` | Responses: - `200` — Overview of wins. `200` response (real production body): ```json [ { "progressiveId": 20155, "highestWinAmountCents": 5902, "lastWinAmountCents": 3149, "lastWinDateTime": "2026-09-15T11:14:38.1735369+02:00", "totalWinAmountCents": 223817310, "triggerCountAllTime": 52576 } ] ``` ## Player Context API Player opt-in state for opt-in jackpots. Versions: v1. Host token: `{{PLAYERCONTEXT_API}}`. ### `GET /optin` (v1) Retrieves the latest opt-in bet for the specified player and product. Returns whether the player is opted in and their bet value if applicable. Returns the current opt-in status and bet value for a player on a given progressive and product. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `PlayerId` | query | string | no | | | `ProgressiveId` | query | integer | no | | | `ModuleId` | query | integer | no | | | `ClientId` | query | integer | no | | | `ProductId` | query | integer | no | | | `api-version` | header | string | yes | | Responses: - `200` — `PlayerOptInResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `500` — `ProblemDetails` — Internal Server Error ### `PUT /optin` (v1) Creates or updates a player opt-in record for the specified product. Pass a null BetValue to opt the player out. Requires a valid user-session JWT in the `Authorization: Bearer` header; the record is keyed on the token's UserId claim, not the PlayerId in the request body. Creates or updates a player's opt-in record for a product. Pass a null `betValueCents` to opt the player out. | Parameter | In | Type | Required | Notes | | --- | --- | --- | --- | --- | | `api-version` | header | string | yes | | Request body: `PlayerOptInUpsertRequest` (see Schemas). Responses: - `200` — `PlayerOptInResponse` — OK - `400` — `ValidationProblemDetails` — Bad Request - `401` — `ProblemDetails` — Unauthorized - `403` — `ProblemDetails` — Forbidden - `500` — `ProblemDetails` — Internal Server Error Authentication: bearer Notes: - Requires a Bearer user-session token — the server trusts the token's `UserId` claim for the record's identity, not the `playerId` in the request body. - Returns `403 Forbidden` if the body's `playerId` does not match the token's `UserId`. ### Player Context API — schemas #### `PlayerOptInResponse` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `optedIn` | boolean | no | | | `betValueCents` | integer | no | nullable | #### `PlayerOptInUpsertRequest` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `playerId` | string | yes | | | `progressiveId` | integer | yes | | | `moduleId` | integer | yes | | | `clientId` | integer | yes | | | `productId` | integer | yes | | | `betValueCents` | integer | yes | nullable | | `optInDateTimeOffset` | string (date-time) | yes | nullable | #### `ProblemDetails` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `type` | string | no | nullable | | `title` | string | no | nullable | | `status` | integer | no | nullable | | `detail` | string | no | nullable | | `instance` | string | no | nullable | #### `ValidationProblemDetails` | Field | Type | Required | Notes | | --- | --- | --- | --- | | `type` | string | no | nullable | | `title` | string | no | nullable | | `status` | integer | no | nullable | | `detail` | string | no | nullable | | `instance` | string | no | nullable | | `errors` | Record | no | | --- ## Reference Lobby Widget (downloadable) A working Jackpot Madness Lobby Widget in three flavours, with identical behaviour. Only the data source differs between demo and production; request/response shapes match the Bridge feeds exactly. - [React (TypeScript) — served as .txt, save as lobbyWidget.tsx](https://docs.jackpots-platform.io/examples/lobbyWidget.tsx.txt) - [Plain JavaScript (ES module)](https://docs.jackpots-platform.io/examples/lobbyWidget.js) - [Vue 3 single-file component (pairs with lobbyWidget.js)](https://docs.jackpots-platform.io/examples/LobbyWidget.vue) Data sources (in `lobbyWidget.tsx` / `lobbyWidget.js`): - `createHttpDataSource({ tickerApi, winHistoryApi })` — product-scoped routes (`/v2/counters?productId`, `/api/v3/WinHistory/product/{productId}/recent|summary`). Not deployed yet. - `createGameScopedHttpDataSource({ tickerApi, winHistoryApi, moduleId, clientId })` — the game-scoped routes live in production today (`/v2/counters?moduleId`, `/api/v3/WinHistory/recent|summary?ModuleId&ClientId[&ProductId]`). - `createSimulatedDataSource()` — demo data with production-shaped ids and types, no network. Props / options: `layout` (`payout-first` — the product owner's default: value and volume of wins paid out over a period first; `pots-first`; `strip`), `periodHours` (default 24), `recentCount`, `levelNames` (display name per `levelIndex`), `jackpotNames` (series filter on `/counters`), `showPayout` / `showRecent` / `showPots`, `productId`, `currencyIsoCode`. Each feed loads independently; a failing feed marks only its own section unavailable. A live game triple for testing: `moduleId` 18661, `clientId` 40300, `productId` 16755 (9 Masks of Fire v94). ```html
``` ## Known gaps (tracked on the Bridge side) - The two feeds' `progressiveId` values coincide only while the site id is zero (true for the live series today), so a join on it is not a contract — match on `levelIndex`. - Neither feed exposes a series beyond `jackpotName`, and a game module can carry pools of several series — a series-scoped widget filters on `jackpotName` client-side. - Lobby opt-in (read state, bet ladders per link group, opt in/out without naming a game) is specified, not built. - Win History hosts may not be reachable from outside the corporate network; the reference widget degrades per feed.