Skip to content

Place a bet, starting the gameround or adding to the open one​

POST
/startGameOrAddBet

Optional. Places a bet. It starts a new gameround on the first bet
and appends a further debit to the open gameround on each later bet.

Use this call only for a game that expects more than one debit.
Use POST /startGameRound for every other game. /startGameRound is
the safer call: it starts exactly one gameround and takes exactly one
debit, so it rejects a duplicate bet that this call accepts. Choose
/startGameOrAddBet only when the game design puts two or more bets in
one gameround.

The request body is identical to POST /startGameRound
(V2_StartGameRoundRequestBody), and so is the reply.

A player has only one open gameround at a time. startGameRound
always marks its debit as the first debit of a new round, so a
second startGameRound on an open round fails with
GAMEROUNDALREADYSTARTED (12). That is correct behaviour; send the
second bet here instead.

How the call chooses between "start" and "add bet". It compares
externalGameProviderRoundId in the request with the round on the
session token (tokenData.gameRound):

  • absent, or different from the round on the token: it starts a new
    gameround and behaves exactly like startGameRound;
  • equal, and debitInformation.externalGameProviderTransactionId
    differs from the first bet of that round: it adds a bet to the open
    round;
  • equal, and debitInformation.externalGameProviderTransactionId
    equals the first bet of that round: it repeats the first bet, so a
    lost first bet is safe to send again.

Sending more than one bet in one round:

  1. send the first bet here with externalGameProviderRoundId set to
    your own round id (hizi.io then uses that value as the gameround
    hash verbatim);
  2. send each later bet here with the same
    externalGameProviderRoundId;
  3. give every bet its own
    debitInformation.externalGameProviderTransactionId;
  4. keep both identifiers to 32 characters or fewer;
  5. send rngResult on every bet, carrying the keys rngCallId,
    result and winAmount (the values may be null and 0);
  6. add one win per bet with POST /addWin, each with its own
    externalGameProviderTransactionId and collect: true to pay the
    player;
  7. close the round with POST /endGameRound.

Limits.

  • endGame and creditInformation are ignored on a bet that is added
    to an open round. Only the call that starts the round reads them.
    Close the round with POST /endGameRound.
  • A repeated debitInformation.externalGameProviderTransactionId on a
    later bet fails with TRANSACTIONALREADYEXISTS (37). It is not a
    silent success.
  • A bet cannot join a round that was started without
    externalGameProviderRoundId: the comparison above can never match.
    Set the field on the first bet even when you expect only one bet.

Retry semantics: idempotent on
debitInformation.externalGameProviderTransactionId while the round is
open. On a lost response, query with POST /getGameRoundInfo rather
than blindly repeating the debit.

Authorizations​

V2AuthId

Game provider ID assigned by hizi.io (Hinterzimmer). Identifies which
shared secret the signature must be verified against. Mandatory on
every game engine / RGS call.

Type
API Key (header: X-H-AUTH-ID)
+
V2Signature

HMAC signature of the request. OpenAPI cannot express a computed
signature, so the scheme is modelled as an apiKey header; the value
is derived per request as follows.

You need a shared secret, which you can retrieve by logging in to the
hizi.io backoffice with your credentials. The signature is a
base64-encoded SHA-256 HMAC digest of a defined set of request
parameters, joined with a hash character (#). This allows the secret
to be shared without ever being sent in the request. A timestamp
(X-H-TIMESTAMP) must also be supplied as a request header and is part
of the signed data.

Outbound (you → hizi.io RGS) — the fields signed are the
serialised JSON body and the timestamp:

X-H-AUTH-SIG = base64(
  HMAC_SHA256( secret, [ JSON.stringify(body), X-H-TIMESTAMP ].join('#') )
)

See the Signing appendix for a complete
reference implementation.

Inbound (hizi.io RGS → your backendQueue) — same primitive, but
the RGS signs a fixed, per-endpoint ordered list of scalar fields
and the body is not hashed. The secret is used both as the HMAC key
and as the first element of the signed string:

X-H-AUTH-SIG = base64( HMAC_SHA256( secret, fields.join('#') ) )
endpoint fields (in order)
GET /getGameConfiguration [ secret, X-H-AUTH-ID, X-H-TIMESTAMP, currency ]
POST /getGameResult [ secret, X-H-AUTH-ID, X-H-TIMESTAMP, gameRound ]

A wrong signature is reported as HTTP 401 / error code 1001
(SIGNATUREWRONG) and must not be retried.

The header family is shared with the Operator API, which documents the
same base64/SHA-256-HMAC/#-joined construction; the set of signed
fields
differs per API and per direction, so do not assume a signer
written for one is reusable for the other without checking the field
list.

Type
API Key (header: X-H-AUTH-SIG)
+
V2Timestamp

ISO 8601 timestamp of the request (e.g. 2023-01-26T11:28:21.429Z).
Mandatory, and included in the signed data of X-H-AUTH-SIG.

Type
API Key (header: X-H-TIMESTAMP)

Parameters​

Header Parameters

X-Request-Id*

Unique ID identifying the call in the logs. Documented as a mandatory
request header for all game engine / RGS calls.

Note: the reference implementation in the
Signing appendix additionally sets
X-Response-Id (a fresh UUID) and, when relaying a request,
X-Forwarded-Response-Id.

Type
string
Required
Example"8c00b93dd861405cbeb7c14fded1e72a"

Request Body​

application/json
JSON
{
  
"token": "83020869-abc0-4123-a95e-ee4f5e8e8343",
  
"externalGameProviderRoundId": "round-0001",
  
"rngResult": {
  
  
"rngCallId": "5cd23259ea4c49e7b955e79321da4365",
  
  
"result": "",
  
  
"winAmount": 0
  
},
  
"debitInformation": {
  
  
"debitAmount": 100,
  
  
"currency": "EUR",
  
  
"externalGameProviderTransactionId": "bet-0001"
  
},
  
"endGame": false
}

Responses​

Bet accepted. gameRoundInfo.hash is the round the bet belongs to,
and equals externalGameProviderRoundId when you supplied one.
gameRoundInfo.status is open, or closed when this call
started the round with endGame: true. gameRoundInfo.stake is
the total staked in the round so far, so it grows with each added
bet.

application/json
JSON
{
  
"tokenData": {
  
  
"operatorId": "string",
  
  
"playerId": "string",
  
  
"gameId": "string",
  
  
"mode": "string",
  
  
"currency": "EUR",
  
  
"currentToken": "string",
  
  
"gameRound": "ff85e29cb4414c89a89829c8411dacc2",
  
  
"walletMode": "string",
  
  
"language": "DE",
  
  
"currencyMultiplier": 1,
  
  
"device": "string",
  
  
"commonDraw": "string"
  
},
  
"balance": {
  
  
"totalBalance": 0,
  
  
"mode": "string",
  
  
"currency": "EUR",
  
  
"balances": [
  
  
  
{
  
  
  
  
"type": "real",
  
  
  
  
"currency": "EUR",
  
  
  
  
"amount": 0
  
  
  
}
  
  
],
  
  
"discountInfo": {
  
  
  
"text": "string",
  
  
  
"currency": "EUR",
  
  
  
"discounts": [
  
  
  
  
{
  
  
  
  
  
"stake": 0,
  
  
  
  
  
"absoluteDiscountAmount": 0,
  
  
  
  
  
"spinsRemaining": 0
  
  
  
  
}
  
  
  
],
  
  
  
"campaignId": "string",
  
  
  
"validFrom": "string",
  
  
  
"validTo": "string"
  
  
},
  
  
"tickets": [
  
  
  
{
  
  
  
  
"count": 0,
  
  
  
  
"stake": 0,
  
  
  
  
"currency": "EUR",
  
  
  
  
"price": 0,
  
  
  
  
"feature": "string",
  
  
  
  
"serial": "string"
  
  
  
}
  
  
],
  
  
"ticketInfo": {
  
  
  
"used": 0,
  
  
  
"granted": 0,
  
  
  
"won": 0,
  
  
  
"isLast": true,
  
  
  
"promotions": {
  
  
  
  
"protocolVersion": 0,
  
  
  
  
"data": "string"
  
  
  
},
  
  
  
"serial": "string"
  
  
}
  
},
  
"gameRoundInfo": {
  
  
"hash": "ff85e29cb4414c89a89829c8411dacc2",
  
  
"status": "open",
  
  
"stake": 0,
  
  
"baseStake": 0,
  
  
"mode": "string",
  
  
"currency": "EUR",
  
  
"game": "string",
  
  
"currencyMultiplier": 0,
  
  
"commonRoundHash": "ff85e29cb4414c89a89829c8411dacc2"
  
},
  
"commonGameRoundInfo": {
  
  
"additionalProperties": "string"
  
},
  
"gameState": [
  
  
{
  
  
  
"hash": "ff85e29cb4414c89a89829c8411dacc2",
  
  
  
"type": "debit",
  
  
  
"processedOn": "string",
  
  
  
"result": {
  
  
  
  
"winAmount": 0,
  
  
  
  
"info": {
  
  
  
  
  
"additionalProperties": "string"
  
  
  
  
}
  
  
  
},
  
  
  
"amountWagered": 0,
  
  
  
"collected": 0,
  
  
  
"reason": "collect 0.37 EUR"
  
  
}
  
],
  
"amountToCollect": 0,
  
"amountCredited": 0,
  
"freePlayInfo": {
  
  
"used": 0,
  
  
"granted": 0,
  
  
"won": 0,
  
  
"isLast": true,
  
  
"promotions": {
  
  
  
"protocolVersion": 0,
  
  
  
"data": "string"
  
  
},
  
  
"serial": "string"
  
},
  
"freePlaysAvailable": [
  
  
{
  
  
  
"currency": "EUR",
  
  
  
"stake": 0,
  
  
  
"count": 0,
  
  
  
"feature": "string",
  
  
  
"serial": "string"
  
  
}
  
],
  
"passThroughData": {
  
  
"additionalProperties": "string"
  
},
  
"promoWinInfo": {
  
  
"referenceId": "string"
  
}
}

Samples​

Powered by VitePress OpenAPI