Skip to content

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

jackpotContributionAmountMonetary value
10.000001
100.00001
1000.0001
10000.001
100000.01
1000000.1
10000001

V2_JackpotPayout

ts
export type V2_JackpotPayout = ({
  jackpotId: string
  jackpotMode: JackpotMode.ENGINE
} | {
  jackpotId: string
  jackpotPayoutAmount: number
  jackpotMode: JackpotMode.VENDOR
})