Skip to content

Endpoints

All endpoints are accessed through the hizi RGS platform. The backendURL and token are obtained from the initial login() call. Requests are JSON POST bodies sent to the backendURL.

login

Exchange the short-lived launch token (provided in the game's launch URL) for a session token and the URLs needed for all subsequent calls. The response also carries the operator's platform settings (gameSettings) that your frontend must honour — things like stake limits, enabled features, UI behaviour and regulatory flags.

Request:

typescript
await login({ loginURL, launchToken });

Response: IConnectReply

typescript
{
  token: string;                       // Session token for subsequent API calls
  backendURL: string;                  // URL for game API calls
  refreshURL: string;                  // URL for refreshing the session
  logoutURL: string;                   // Logout URL
  webSocketURL?: string;               // WebSocket URL (optional)
  balance?: IBalanceReply;             // Player balance
  gameSettings?: IGameSettings;        // Operator platform settings — read this!
  tokenData?: ITokenData;              // Token metadata (playerId, currency, mode, …)
  freePlaysAvailable?: IFreePlayInfo[]; // Available free plays
}

Read gameSettings before showing the game

gameSettings is operator- and jurisdiction-specific and must drive your UI. The frontend is responsible for clamping/validating stakes and respecting every enabled/disabled flag; the engine does not re-enforce these on your behalf.

Typical fields to apply:

  • minStake / maxStake / maxPackageStake — clamp the stake selector and buy-feature prices.
  • customStakes / defaultStakeIndex / forceDefaultStake — override the game's own stake list.
  • maxExposure — cap the maximum possible win shown/allowed.
  • autoplayEnabled, autoplayLossLimitRequired, autoplayShowTotalStake — gate the autoplay UI.
  • gambleEnabled, turboEnabled, stopEnabled, partialCollectEnabled, packageBuyEnabled — enable/disable feature buttons.
  • displayRTP / displayXRTP / showExactRTP / displayWinOdds / displayJackpotOdds — RTP/odds disclosure rules.
  • forceOrientation, disableFullScreenMobile, hideCompanyLogo, displayClock, abbreviateAmounts, displayNetPosition, hideDemoBalance, displaySessionTimer — presentation rules.
  • historyURL, homeURL, topupURL, lossLimitURL, homeEnabled, redirectTarget — external navigation.
  • reportAnimationEnd — if true, call reportAnimationEnd after every win animation.
  • operatorHandlesErrors, translateErrors, preventRedirect, refreshDisabled — error/session handling.

See IGameSettings for the full field list. Operators may also supply extra fields beyond the typed ones — the index signature [key: string]: unknown exposes them.

Stake limits precedence

Always intersect the game's own stake list (loadConfigconfig.stakes) with gameSettings.minStake / gameSettings.maxStake (and use gameSettings.customStakes when provided). The operator's limits override the game's defaults.


loadConfig

Load the game configuration including available stakes, RTP, and buy-features.

Request:

typescript
await loadConfig({ backendURL, token });

Under the hood, this sends:

json
{
  "op": "loadConfig",
  "token": "<session-token>"
}

Response: ILoadConfigReply

typescript
{
  config: {
    gameCode: string;
    gameType?: string;             // Game type (e.g. 'slot', 'mines', 'crash', 'keno', 'plinko')
    stakes?: number[];             // Available stake amounts (optional)
    rtp: number;                   // Return to player percentage
    maxPayoutCap?: number;         // Maximum payout cap
    maxWagerableWin?: number;       // Maximum win amount eligible for wagering
    minWagerableWin?: number;      // Minimum win amount eligible for wagering
    version: string;               // Engine version
    buyFeatures?: IBuyFeatureOption[]; // Available buy-features (with `id` added)
    wagerFeatures?: string[];            // Relative wager features (e.g. ["color-red", "color-black", ...])
    wagerStakeFeatures?: string[];       // Absolute cashout wager features (e.g. mines/frogger steps)
    progressionCounters?: IProgressionCounterConfig[]; // Progression counter configs
    progressionCounterValues?: Record<string, number>; // Current counter values (0.0–1.0)
    [key: string]: unknown;            // Additional fields from loadConfig.json
  };
  tokenData: ITokenData;              // Updated token data
  balance?: IBalanceReply;             // Player balance
  gameResult?: IGameResult;            // Last game result (if resuming)
  gameRoundInfo?: IGameRoundInfo;      // Game round info (if resuming)
  freePlaysAvailable?: IFreePlayInfo[]; // Available free plays
  previousResults?: IGameResult[];     // Previous game results
  amountToCollect?: number;            // Uncollected amount
}

Key fields:

FieldDescription
config.gameTypeGame type identifier set by hizi-engine-creator (e.g. 'slot', 'mines', 'crash'). Use to select game-specific UI.
config.stakesArray of available stake amounts in minor currency units (optional — some games use operator-defined custom stakes)
config.rtpReturn to player percentage (e.g., 95 for 95%)
config.buyFeaturesAvailable buy-feature options. See buy-features
config.wagerFeaturesAvailable wager feature names (absent if game has no wager features). See gamble-features
config.progressionCountersProgression counter configuration. See Progression Counters
config.progressionCounterValuesCurrent counter values per player (0.0–1.0 range)
gameResultThe last game result if the player has an incomplete round to resume

placeBet

Place a bet and receive a game result, or continue an in-progress round.

Request:

typescript
// New spin
await placeBet({ backendURL, token, stake });

// Continue multi-step round
await placeBet({ backendURL, token });

// Buy feature
await placeBet({
  backendURL,
  token,
  stake,
  featureToBuy: featureId,
});

Under the hood:

json
{
  "op": "placeBet",
  "token": "<session-token>",
  "stake": 100,
  "featureToBuy": "freespin"
}

Options: IPlaceBetOptions

FieldTypeRequiredDescription
backendURLstringYesBackend URL from login response
tokenstringYesSession token
stakenumberNoStake amount. Required for the first call of a game round.
useTicketbooleanNoUse a free play ticket
useTicketFeatureTypestringNoFeature type of the ticket
featureToBuystringNoFeature to buy (e.g., 'freespin'). Engine derives the price from the stake.
playerChoiceIndexnumberNoIndex of the selected option when engineData.playerChoice is set
additionalDataRecord<string, unknown>NoAdditional game-specific parameters

Response: IPlaceBetReply

typescript
{
  result: IGameResult;            // The game result
  tokenData: ITokenData;          // Updated token data
  balance?: IBalanceReply;        // Updated balance
  gameRoundInfo?: IGameRoundInfo; // Game round status
  amountToCollect?: number;       // Uncollected amount
}

The key payload is result - an IGameResult:

typescript
{
  // Your scenario data (from hizi engine generator)
  scenario: Record<string, unknown>;

  // Engine state
  engineData: {
    // Fixed-odds (entries-DB) games only — omitted by rules-engine games
    // such as blackjack and crash.
    entryIndex?: number;
    scenarioInfo?: IScenarioInfo;
    spinInfo?: ISpinInfo[];
    playerChoice?: TPlayerChoiceFeatureAward[];
    currentFeature?: string;
    nextFeature?: string;
    progressionCounters?: Record<string, number>;
    canCollect?: boolean;
    inProgress: boolean;
  };

  // Cumulative win (multiplier of stake)
  totalWin: number;
}

Decision logic after receiving a response:

ConditionAction
engineData.playerChoice is setPresent options to the player, then call placeBet with playerChoiceIndex: N
engineData.inProgress === trueCall placeBet({ backendURL, token }) to continue
engineData.inProgress === false and totalWin > 0If game has wager features: call collect() to cash out. Otherwise the round auto-ends - no action needed.
engineData.inProgress === false and totalWin === 0Round complete, enable next spin

TIP

Games without wager features (config.wagerFeatures is absent) always auto-end the round when the game completes. Winnings are credited automatically - you do not need to call collect().


collect

Collect winnings after a completed round. Only available for games with wager features configured (config.wagerFeatures is present). Games without wager features auto-end the round and credit winnings automatically.

Request:

typescript
// Collect full amount
await collect({ backendURL, token });

// Collect partial amount
await collect({ backendURL, token, amount });

Under the hood:

json
{
  "op": "collect",
  "token": "<session-token>",
  "collectAmount": 5000
}

Options: ICollectOptions

FieldTypeRequiredDescription
backendURLstringYesBackend URL from login response
tokenstringYesSession token
amountnumberNoAmount to collect. If omitted, collects the full available amount

Response: ICollectReply

typescript
{
  amountCredited: number;  // Amount credited to balance
  amountToCollect: number; // Amount that was requested
  balance?: IBalanceReply; // Updated balance
  tokenData: ITokenData;   // Updated token data
}

WARNING

Only call collect when:

  • The game has wager features (config.wagerFeatures is present)
  • engineData.canCollect === true
  • totalWin > 0 (there are winnings to collect)

Calling collect on a game without wager features will return an error.


pfVerify

Replay any past round purely from its revealed seeds (and the player actions that drove it, where the round had any). Re-runs the exact game logic the live round ran and returns the full result plus the per-call RNG audit, so a client can compare against what they recorded at round time.

Provably-fair only — only meaningful when the round ran with config.rng === 'pf'. The endpoint never touches the wallet, progression counters, or operator caps; it's pure compute.

Request:

typescript
import { pfVerify } from '@hizi.io/engine-sdk';

const reply = await pfVerify({
  backendURL,
  token,                              // current session token (auth + gameId routing)
  serverSeed: pf.revealedServerSeed,
  clientSeed: pf.clientSeed,
  stake: 100,                         // the stake the round opened with
  featureToBuy: 'freespin',           // if the round opened on a buy feature
  initialData: { /* … */ },           // blackjack side bets
  bets: [ /* … */ ],                  // roulette / crash opening bets
  playerNumbers: [ /* … */ ],         // keno picks
  actions: [
    { playerChoiceIndex: 0 },         // fixed-odds wager choice
    { pickPosition: 12 },             // mines pick
    { action: { kind: 'hit' } },      // blackjack action (TRulesAction shape)
  ],
});

Under the hood, the SDK POSTs to backendURL:

json
{ "op": "pfVerify", "token": "<session-token>", "serverSeed": "…", "clientSeed": "…", "…": "…" }

Options: IPfVerifyOptions

FieldTypeRequiredDescription
backendURLstringYesBackend URL from the login response.
tokenstringYesSession token. Used only to resolve the gameId → game config; no wallet calls.
serverSeedstringYesThe revealed server seed from the round's pf block.
clientSeedstringYesThe client seed bound to that round.
startNoncenumberNoDefaults to 0. Set it if your round opened mid-stream against an existing PF session.
stakenumberNoRequired by games that need the stake to settle (blackjack settle math, frogger / fixed-odds wager).
featureToBuystringNoMirror the round's opening featureToBuy (mines mine-count, slot bonus buy, …).
initialDataRecord<string, unknown>NoMirror the round's opening payload — currently blackjack { sideBets }.
betsunknown[]NoRoulette IRouletteBet[] or crash IBet[] — the round's opening bets.
playerNumbersnumber[]NoKeno: the player numbers, if the round was opened with explicit picks.
actionsIPfVerifyAction[]NoContinuation actions in order. Shape per game — see the game's Provably Fair section under Games.

Response: IPfVerifyReply

typescript
{
  rngData: IRngDataEntry[];   // per-call audit, same shape as the live `pf.rngData`
  steps: IGameResult[];       // per-step game outcomes, terminal step last (length 1 for one-shots)
}

Two fields, two checks:

  1. Audit replay — diff rngData element-wise against the round's saved pf.rngData. Exact equality on 'int' rows, float-tolerance equality on 'double' rows. A swapped server seed would produce different draws, so a passing diff transitively proves the revealed seed is the one that was committed to.
  2. Result replay — compare each steps[i].scenario / steps[i].totalWin to what the live round returned at the matching step. For one-shot games that's just steps[0]; for multi-step rounds (blackjack, mines, hi-lo) it's the full per-step chain.

If both line up the round was determined purely by (serverSeed, clientSeed, actions); the engine could not have rigged it.

engineData is preserved

Each step is a full IGameResult, so steps[i].engineData carries the engine's per-step flow-control state — playerChoice (fixed-odds wager-feature offerings), inProgress, nextFeature, etc. Useful when you also want to verify the round's flow (e.g. confirm a fixed-odds round surfaced the expected wager choices) rather than just the final outcome.

Defence-in-depth commit check

If you want an explicit commitment check on top of the audit replay, compute SHA-256(serverSeed) client-side and compare to the serverSeedHash you saved before the round opened — one crypto.subtle.digest call. The engine does not need to return this value.

Scope

pfVerify skips the operator-side post-processing the live placeBet runs — progression counters, gameSettings.maxExposure caps, supplemental stake debits. Those are not derivable from the PF commitment. Verification covers the RNG draws and the game logic that consumes them.

Crash

Crash player-cashout timing is wall-clock-driven, not seed-derivable. pfVerify for crash returns the committed scenario.maxMultiplier only — that's the entire seed-derived surface. Bet settlements are operator-audited.

See Provably Fair for the underlying HMAC-SHA512 protocol and how the seeds are derived from (serverSeed, clientSeed, nonce).


refresh

Refresh an expired session token. Call this when API requests return SESSIONINVALID or NOTLOGGEDON errors.

Request:

typescript
await refresh(refreshURL);

The refreshURL is obtained from the initial login() response (result.refreshURL).

Response: IConnectReply

typescript
{
  token: string;                     // New session token
  backendURL: string;                // Backend URL (may change)
  refreshURL: string;                // New refresh URL
  logoutURL: string;                 // Logout URL
  webSocketURL?: string;             // WebSocket URL
  balance?: IBalanceReply;           // Player balance
  gameSettings?: IGameSettings;      // Platform settings
  tokenData?: ITokenData;            // Token metadata
  freePlaysAvailable?: IFreePlayInfo[]; // Available free plays
}

TIP

After a successful refresh, update your stored token, backendURL, and refreshURL with the new values from the response.


reportAnimationEnd

Notify the backend that the game animation has finished. Used when the operator requires animation-end reporting (see gameSettings.reportAnimationEnd).

Request:

typescript
await reportAnimationEnd({ backendURL, token });

updateBalance

Request an updated balance from the backend.

Request:

typescript
await updateBalance({ backendURL, token });