Appearance
Data structures
This page lists the wire types for the Game Studio API V2. The @hoelle/apiv2-definitions package publishes these types. This page groups the types into request bodies, replies, and shared/nested types.
API V2 request bodies
V2_TestPingRequestBody
ts
export interface V2_TestPingRequestBody {
testData: unknown;
}V2_StartGameRoundRequestBody
ts
export interface V2_StartGameRoundRequestBody {
token: string;
rngResult: GameRNGResult;
debitInformation: DebitInformation;
creditInformation?: CreditInformation;
endGame: boolean;
closeOpenGame?: boolean;
useJackpot?: boolean;
betData?: BetData;
externalGameProviderRoundId?: string;
}Note: externalGameProviderRoundId is optional. If you use it, do not exceed 32 characters.
Not currently implemented
The engine ignores useJackpot now. The jackpot feature is specified, but it is not yet live. See Jackpot data types.
V2_EndGameRoundRequestBody
ts
export interface V2_EndGameRoundRequestBody {
token: string;
gameRound: string;
externalGameProviderTransactionId?: string;
}V2_GetGameRoundDetailsRequestBody
ts
export interface V2_GetGameRoundDetailsRequestBody {
token: string;
gameRound: string;
}V2_AddWinRequestBody
ts
export interface V2_AddWinRequestBody {
token: string;
gameRound: string;
rngResult: GameRNGResult;
collect?: boolean;
externalGameProviderTransactionId?: string;
jackpotPayout?: V2_JackpotPayout[];
}Not currently implemented
The engine ignores jackpotPayout now. See Jackpot data types.
V2_WagerWinRoundRequestBody
ts
export interface V2_WagerWinRoundRequestBody {
token: string;
gameRound: string;
rngResult: GameRNGResult;
wagerInformation: WagerInformation;
}V2_CollectWinRoundRequestBody
ts
export interface V2_CollectWinRoundRequestBody {
token: string;
gameRound: string;
collectInformation: CollectInformation;
}V2_GetUncollectedAmountRequestBody
ts
export interface V2_GetUncollectedAmountRequestBody {
token: string;
gameRound: string;
}V2_AddSpinCounterGameStateRequestBody
ts
export interface V2_AddSpinCounterGameStateRequestBody {
token: string;
gameRound: string;
counterType: string;
rngResult: GameEventRNGResult;
gameStateResult: object | string;
}V2_GetAvailableSpinCounterRequestBody
ts
export interface V2_GetAvailableSpinCounterRequestBody {
token: string;
gameRound: string;
counterType: string;
}V2_GetRandomResultRequestBody
ts
export interface V2_GetRandomResultRequestBody {
token: string;
rngEndPoint: string;
rngPayload: {
count?: number;
min?: number;
max: number;
};
}V2_GetTokenForGameRoundRequestBody
ts
export interface V2_GetTokenForGameRoundRequestBody {
gameRound: string;
}V2_GetTokenDataRequestBody
ts
export interface V2_GetTokenDataRequestBody {
token: string;
}V2_GetLastGamesRequestBody
ts
export interface V2_GetLastGamesRequestBody {
token: string;
maxRecords?: number; // default is 50
maxDays?: number; // default is 30
}V2_GetOperatorSettingsQuery
ts
export interface V2_GetOperatorSettingsQuery {
game: string;
operator: string;
currency: string;
}V2_VoidGameRoundRequestBody
ts
export interface V2_VoidGameRoundRequestBody {
gameRound: string;
token: string;
}Note: The published type declares token as optional. The engine requires it at runtime. Always send it.
API V2 replies
V2_GameAPIReply
ts
export interface V2_GameAPIReply {
tokenData: V2_GameToken;
balance?: GameAPIBalanceReply;
gameRoundInfo?: {
hash: string;
status: string;
stake: number; // amount actually staked, in player currency minor units (already multiplied)
baseStake?: number; // equals stake for a normal round; on buy-feature rounds records the underlying stake. NOT stake / currencyMultiplier
mode: string;
currency: string;
game: string;
currencyMultiplier?: number;
commonRoundHash?: string;
};
commonGameRoundInfo?: CD_InfoReply; // common-draw round info, only for common-draw games
gameState?: Array<V2_GameAPIGameState>;
amountToCollect?: number;
amountCredited?: number;
freePlayInfo?: {
used: number;
granted: number;
won: number;
isLast: boolean;
promotions?: {
protocolVersion: number;
data: unknown;
};
serial: string;
};
freePlaysAvailable?: {
currency: string;
stake: number;
count: number;
feature?: string;
serial: string;
}[];
passThroughData?: PassThroughData; // operator-specific pass-through payload
promoWinInfo?: PromoWinInfo;
}
export interface PromoWinInfo {
referenceId: string;
}
export interface PassThroughData {
protocol: number; // OperatorProtocol enum value, e.g. 1 = HOELLE_NATIVE
clientMessage?: NativeClientMessage;
}
export interface NativeClientMessage {
title: string;
msg: string; // the text to display to the player
stopAutoPlay?: boolean;
buttons?: {
label: string;
url?: string;
}[];
operatorHandlesDisplay?: boolean;
}passThroughData.clientMessage.msg, when present, is the only field meant for player display for a responsible-gambling prompt. The operator sets this text from its own curated, localized source (for example, Playtech POP's messageArray[].accountMsg). The operator-protocols component maps this text through as-is. The field is present on the reply body of the call that triggered the prompt (most commonly startGameRound). It appears only if the operator's own response included that text in the first place. The Game Studio API does not generate or guarantee this text for every error code. It is a straight pass-through. The mapping itself is generic. Any Playtech response that carries a messageArray passes through, regardless of which error code triggered it. This field is present in production for both X-H-ERROR-ID 38 (REALITYCHECK) and 11 (BETLIMITREACHED). Do not assume it is absent for either code. Whether it is included for a given decline depends on the operator's own account and responsible-gambling configuration on Playtech's side. It does not depend on the error code or on anything controllable from the Game Studio API. Treat presence as per-operator and per-account, not per-error-code. Always keep a static fallback ready for when the field is missing. Do not use the X-H-ERROR-MSG header for display, in either case. See Response Codes. This header is documented as log-only. It is not localized. When clientMessage is absent, this API provides no player-facing text for that call. The game studio needs its own static fallback copy.
buttons is carried through as-is from the operator's own protocol. Today it only ever contains a single generic acknowledgement button. The button does not distinguish between a continue action and a stop action. It has no url field to call back. Treat it as informational. Render your own dismiss control (for example, a "Home" or "OK" button). Do not try to interpret it. For X-H-ERROR-ID 38 (REALITYCHECK) specifically, retry the same startGameRound call after the player dismisses the message. There is no separate acknowledgement endpoint reachable from the Game Studio API. RGS-to-RGS studios have no v2 equivalent of the native protocol's internal reality-check callback.
V2_ConnectReply
ts
export interface V2_ConnectReply extends V2_GameAPIReply {
backendUrl: string;
refreshUrl: string;
logoutUrl: string;
webSocketUrl?: string;
token: string;
gameSettings: GameSettings;
gameVariables: Partial<GameVariables>;
// please contact support for available options
operatorProtocol: number;
featuresAvailable?: ExternalFeaturePackageDefinition[];
tokenData: V2_GameToken;
}
export interface ExternalFeaturePackageDefinition {
game: string;
type: string;
rtp: number;
value: number;
description?: string;
}V2_GameAPIGetUncollectedAmountReply
ts
export interface V2_GameAPIGetUncollectedAmountReply {
tokenData: V2_GameToken;
amountToCollect?: number;
}V2_GameAPIAddSpinCounterGameStateReply
ts
export interface V2_GameAPIAddSpinCounterGameStateReply extends V2_GameAPIReply {
spinsAvailable: number;
}V2_GameAPIGetAvailableSpinCounterReply
ts
export interface V2_GameAPIGetAvailableSpinCounterReply extends V2_GameAPIGetUncollectedAmountReply {
spinsAvailable: number;
}V2_GameAPIRngReply
ts
export interface V2_GameAPIRngReply {
tokenData: V2_GameToken;
values: number[];
rngRequestId: string;
}V2_GetTokenDataReply
ts
export interface V2_GetTokenDataReply {
tokenData: V2_GameToken;
}V2_GetTokenForGameRoundReply
ts
export interface V2_GetTokenForGameRoundReply extends V2_GetTokenDataReply {
}V2_GetLastGamesReply
ts
export interface V2_GetLastGamesReply {
gameRoundList: Record<string, unknown>[];
}Shared and nested types
V2_GameToken
ts
export type DeviceModes = 'desktop' | 'mobile';
export interface V2_GameToken {
operatorId: string;
playerId: string;
gameId: string;
mode: string;
currency: string;
currentToken?: string;
gameRound?: string; // this holds any open gameroundhash
walletMode: string;
language: string;
currencyMultiplier: number;
device?: DeviceModes;
commonDraw?: string;
}GameAPIBalanceReply
ts
export type GameModes = 'DEMO' | 'REAL' | 'HISTORY';
export interface BalanceEntry {
type: string;
currency: string;
amount: number;
}
interface DiscountEntry {
stake: number;
absoluteDiscountAmount: number;
spinsRemaining?: number;
}
export interface DiscountInfo {
text: string;
currency: string;
discounts: DiscountEntry[];
campaignId?: string;
validFrom?: string;
validTo?: string;
}
export interface GameAPIBalanceReply {
totalBalance: number;
mode: GameModes;
currency: string;
balances: BalanceEntry[];
discountInfo?: DiscountInfo;
tickets?: TicketEntry[];
ticketInfo?: TicketWonInfo;
}TicketEntry
ts
export interface TicketEntry {
count: number;
stake: number;
currency: string;
price?: number;
feature?: string;
serial: string;
}TicketWonInfo
ts
export interface TicketWonInfo {
used: number;
granted: number;
won: number;
isLast: boolean;
promotions?: {
protocolVersion: number;
data: unknown;
};
serial: string;
}GameRNGResult
ts
export type BetData = Record<string, unknown>;
export interface GameRNGResult {
rngCallId: string | string[];
result: unknown;
winAmount?: number;
betData?: BetData;
}GameEventRNGResult
ts
export interface GameEventRNGResult {
rngCallId: string | string[];
result: GameEventRNGResultCounter;
winAmount?: number;
}
export interface GameEventRNGResultCounter {
awarded?: number;
used?: number;
}DebitInformation
ts
type GameTransactionStatus = 'success' | 'error' | 'retrying';
interface GameTransaction {
currency: string;
status?: GameTransactionStatus;
externalGameProviderTransactionId?: string;
}
interface UseTicketDebitInformation {
useTicket: boolean;
featureType?: string;
}
interface BuyFeatureDebitInformation {
featureToBuy: string;
featurePrice: number;
featureResultSetSelected: number;
}
export interface DebitInformation extends GameTransaction {
debitAmount: number;
useTicketInfo?: UseTicketDebitInformation;
buyFeatureInfo?: BuyFeatureDebitInformation;
jackpotContribution?: V2_JackpotContribution[];
}Not currently implemented
The engine currently ignores the jackpotContribution field here and the jackpotPayout field on CreditInformation, CollectInformation, and WagerInformation below. See Jackpot data types.
CreditInformation
ts
export interface CreditInformation extends GameTransaction {
creditAmount: number;
jackpotPayout?: V2_JackpotPayout[];
}CollectInformation
ts
export interface CollectInformation extends GameTransaction {
creditAmount?: number;
jackpotPayout?: V2_JackpotPayout[];
}WagerInformation
ts
export interface WagerInformation extends GameTransaction {
wagerAmount: number;
winAmount?: number;
jackpotPayout?: V2_JackpotPayout[];
}V2_GameAPIGameState
ts
export interface V2_GameAPIGameState {
hash: string;
type: string;
processedOn?: Date;
result?: {
winAmount?: number;
info: Record<string, unknown>;
};
amountWagered?: number;
collected?: number;
reason?: string;
}Additional data types used in responses to frontend
The Game Studio API sends these structures in response to connect requests from the frontend during game startup (GET V2_API_ENDPOINT/connect).
V2_GameSettings
Exported as GameSettings from @hoelle/apiv2-definitions.
ts
export enum ForcedOrientation {
none = 0,
landscape = 1,
portrait = 2
}
export enum DisplayWinOdds {
maxPayout = 'maxPayout',
maxWin = 'maxWin',
}
export interface GameSettings {
autoplayEnabled: boolean;
autoplayLossLimitRequired: boolean;
displayCoins: boolean;
displayJackpotOdds: boolean;
displayRTP: boolean;
displayXRTP: boolean;
forceOrientation: ForcedOrientation;
gambleEnabled: boolean;
historyURL: string;
homeURL: string;
loadMsg: string;
maxExposure: number;
maxStake: number;
maxPackageStake: number;
minStake: number;
minLoadTime: number;
minSpinTime: number;
multipleInstancesAllowed: boolean;
rcDisplayWinLoss: boolean;
rcEnabled: boolean;
rcInterval: number;
stopEnabled: boolean;
topupURL: string;
turboEnabled: boolean;
homeEnabled: boolean;
dynamicMinSpinTime: boolean;
redirectTarget: 'self' | 'parent' | 'top';
packageBuyEnabled: boolean;
defaultStakeIndex: number;
operatorHandlesErrors: boolean;
displayClock: boolean;
isSocial: boolean;
displayCurrency: boolean;
customStakes: number[];
lossLimitURL: string;
partialCollectEnabled: boolean;
hideCompanyLogo: boolean;
abbreviateAmounts: boolean;
showExactRTP: boolean;
jurisdiction: string;
forceDefaultStake: boolean;
disableFullScreenMobile: boolean;
displayPaytableOnEnterGame: boolean;
doNotStoreSettings: string[];
sessionTimeoutInSeconds: number;
displayNetPosition: boolean;
hideDemoBalance: boolean;
preventRedirect: boolean;
refreshDisabled: boolean;
displayWinOdds: DisplayWinOdds[];
displaySessionTimer: boolean | string;
skipWinsEqualToOrLessThanStake: boolean;
reportAnimationEnd: boolean;
launcherType: 'reelLink' | 'online';
autoplayShowTotalStake: boolean;
translateErrors: boolean;
currencyToDisplay: string;
}V2_GameVariables
Exported as GameVariables from @hoelle/apiv2-definitions.
ts
export interface GameVariables {
rcElapsed: number;
}Jackpot data types
Not currently implemented
The jackpot payload below (jackpotContribution, jackpotPayout, and the V2_JackpotMode, V2_JackpotContribution, V2_JackpotPayout types, added in docs v1.8) is specified but not yet live in the game engine. The engine currently ignores these fields. The engine also ignores useJackpot on V2_StartGameRoundRequestBody. This section keeps the specification for the planned feature. Do not build against it yet.
V2_JackpotMode
ts
export enum JackpotMode {
ENGINE = 'engine',
VENDOR = 'vendor'
}V2_JackpotContribution
ts
export type V2_JackpotContribution = ({
jackpotId: string
jackpotMode: JackpotMode.ENGINE
} | {
jackpotId: string
jackpotContributionAmount: number // 6 decimal digits (check JackpotContributionScale)
jackpotMode: JackpotMode.VENDOR
})JackpotContributionScale
| jackpotContributionAmount | Monetary value |
|---|---|
| 1 | 0.000001 |
| 10 | 0.00001 |
| 100 | 0.0001 |
| 1000 | 0.001 |
| 10000 | 0.01 |
| 100000 | 0.1 |
| 1000000 | 1 |
V2_JackpotPayout
ts
export type V2_JackpotPayout = ({
jackpotId: string
jackpotMode: JackpotMode.ENGINE
} | {
jackpotId: string
jackpotPayoutAmount: number
jackpotMode: JackpotMode.VENDOR
})