1. Introduction

This document describes the API provided by the Gateway and the contract for reverse integration.

2. Authentication and Security

All requests to the Gateway API must be authenticated using a signature-based mechanism. The following headers are required for every request:

Header Description

X-Api-Key

Your unique API key provided by the Gateway.

X-Nonce

A unique UUID v4 string for each request to prevent replay attacks.

X-Timestamp

Current UNIX timestamp in milliseconds.

X-Signature

HMAC-SHA256 signature generated using your API secret.

2.1. Signature Generation Logic

The signature is a lowercase hex-encoded HMAC-SHA256 hash of a message string.

  1. Construct the message: Concatenate the timestamp and the nonce, separated by a colon (:). message = timestamp + ":" + nonce

  2. Generate HMAC: Use your API Secret as the key to generate an HMAC-SHA256 hash of the message.

  3. Encode: Convert the resulting bytes into a lowercase hexadecimal string.

2.1.1. Example (Kotlin)

val message = "$timestamp:$nonce"
val secretKeySpec = SecretKeySpec(apiSecret.toByteArray(Charsets.UTF_8), "HmacSHA256")
val mac = Mac.getInstance("HmacSHA256").apply {
    init(secretKeySpec)
}
val signature = Hex.encodeHexString(mac.doFinal(message.toByteArray(Charsets.UTF_8)))

3. Gateway API (Operator → Gateway)

The following endpoints are called by the Operator to interact with the Gateway.

3.1. List Available Games

GET /api/games

Retrieve all games enabled for the operator.

3.1.1. Example Request

GET /api/games?operatorName=test-operator HTTP/1.1
x-api-key: 49cba8e8-a848-4a10-991b-405f1992ade7
x-signature: c944a1ad41608f2f1e61830d2b3dfc88f97a336d131aa4f81241e03fa76d95aa
x-timestamp: 1767618074167
x-nonce: 33d3af40-8aa6-411b-af6a-8a823eaab614
Host: localhost:8080

3.1.2. Curl Request

$ curl 'http://localhost:8080/api/games?operatorName=test-operator' -i -X GET \
    -H 'x-api-key: 49cba8e8-a848-4a10-991b-405f1992ade7' \
    -H 'x-signature: c944a1ad41608f2f1e61830d2b3dfc88f97a336d131aa4f81241e03fa76d95aa' \
    -H 'x-timestamp: 1767618074167' \
    -H 'x-nonce: 33d3af40-8aa6-411b-af6a-8a823eaab614'

3.1.3. Example Response

HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Content-Length: 627
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 0
Referrer-Policy: no-referrer

{
  "content" : [ {
    "name" : "western-express",
    "publicId" : "494c8740-d798-4f54-8328-22e6212b6703",
    "images" : [ "https://images.example.com/cover.jpg" ]
  } ],
  "pageable" : {
    "pageNumber" : 0,
    "pageSize" : 50,
    "sort" : {
      "unsorted" : true,
      "sorted" : false,
      "empty" : true
    },
    "offset" : 0,
    "unpaged" : false,
    "paged" : true
  },
  "totalPages" : 1,
  "totalElements" : 1,
  "last" : true,
  "numberOfElements" : 1,
  "first" : true,
  "size" : 50,
  "number" : 0,
  "sort" : {
    "unsorted" : true,
    "sorted" : false,
    "empty" : true
  },
  "empty" : false
}

3.2. Initialize Session

POST /api/session/init

Starts a new game session for a player.

3.2.1. Example Request

POST /api/session/init HTTP/1.1
x-api-key: 49cba8e8-a848-4a10-991b-405f1992ade7
x-signature: 0c105a739d086b328d3f5374c4a74c83a911f879cb29bfe3db447cf607a9dd97
x-timestamp: 1767618074209
x-nonce: 4f557480-9c3d-4df3-9203-ac44a9dd18a5
Content-Type: application/json
Content-Length: 232
Host: localhost:8080

{
  "operatorName" : "test-operator",
  "gameIdentifier" : "western-express",
  "playerId" : "player-123",
  "username" : "test-user",
  "locale" : "en",
  "deviceType" : "DESKTOP",
  "brandId" : "test-operator",
  "mode" : "DEMO"
}

3.2.2. Curl Request

$ curl 'http://localhost:8080/api/session/init' -i -X POST \
    -H 'x-api-key: 49cba8e8-a848-4a10-991b-405f1992ade7' \
    -H 'x-signature: 0c105a739d086b328d3f5374c4a74c83a911f879cb29bfe3db447cf607a9dd97' \
    -H 'x-timestamp: 1767618074209' \
    -H 'x-nonce: 4f557480-9c3d-4df3-9203-ac44a9dd18a5' \
    -H 'Content-Type: application/json' \
    -d '{
  "operatorName" : "test-operator",
  "gameIdentifier" : "western-express",
  "playerId" : "player-123",
  "username" : "test-user",
  "locale" : "en",
  "deviceType" : "DESKTOP",
  "brandId" : "test-operator",
  "mode" : "DEMO"
}'

3.2.3. Example Response

HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Content-Length: 72
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 0
Referrer-Policy: no-referrer

{
  "url" : "http://localhost:8080/game/western-express?sessionId=123"
}

3.3. Initialize Real Session

POST /api/session/init

Starts a new real money game session for a player. This request requires additional fields such as currencyCode, balance, and ipAddress. Optionally, a sessionId can be provided if the operator wants to track it.

3.3.1. Example Request

POST /api/session/init HTTP/1.1
x-api-key: 49cba8e8-a848-4a10-991b-405f1992ade7
x-signature: ff8d66b6e548ed1dfe4cd6d2d59269073e453d0e1c5e521a7eced0269a11f9db
x-timestamp: 1767618073963
x-nonce: 5f6f127c-8003-46cc-bd18-c694f77cc990
Content-Type: application/json
Content-Length: 329
Host: localhost:8080

{
  "operatorName" : "test-operator",
  "gameIdentifier" : "western-express",
  "playerId" : "player-123",
  "username" : "test-user",
  "locale" : "en",
  "deviceType" : "DESKTOP",
  "brandId" : "test-operator",
  "currencyCode" : "FUN",
  "balance" : 1000,
  "ipAddress" : "127.0.0.1",
  "sessionId" : null,
  "mode" : "REAL"
}

3.3.2. Curl Request

$ curl 'http://localhost:8080/api/session/init' -i -X POST \
    -H 'x-api-key: 49cba8e8-a848-4a10-991b-405f1992ade7' \
    -H 'x-signature: ff8d66b6e548ed1dfe4cd6d2d59269073e453d0e1c5e521a7eced0269a11f9db' \
    -H 'x-timestamp: 1767618073963' \
    -H 'x-nonce: 5f6f127c-8003-46cc-bd18-c694f77cc990' \
    -H 'Content-Type: application/json' \
    -d '{
  "operatorName" : "test-operator",
  "gameIdentifier" : "western-express",
  "playerId" : "player-123",
  "username" : "test-user",
  "locale" : "en",
  "deviceType" : "DESKTOP",
  "brandId" : "test-operator",
  "currencyCode" : "FUN",
  "balance" : 1000,
  "ipAddress" : "127.0.0.1",
  "sessionId" : null,
  "mode" : "REAL"
}'

3.3.3. Example Response

HTTP/1.1 200 OK
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Content-Length: 72
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 0
Referrer-Policy: no-referrer

{
  "url" : "http://localhost:8080/game/western-express?sessionId=123"
}

3.4. Register Free Spins

POST /api/v1/free-spins

Registers new free spins for a player.

3.4.1. Example Request

POST /api/v1/free-spins HTTP/1.1
x-api-key: 49cba8e8-a848-4a10-991b-405f1992ade7
x-signature: ebccfc50b758b5fb7137df123b0c5897653fe1a66b74491f4b1d106ef83b1218
x-timestamp: 1767618074261
x-nonce: d9080c43-3f78-438c-95f2-51391af5e248
Content-Type: application/json
Content-Length: 409
Host: localhost:8080

{
  "player" : {
    "playerIdentifier" : "player-123",
    "currencyCode" : "FUN"
  },
  "freeSpins" : [ {
    "gameIdentifier" : "western-express",
    "amount" : 10,
    "quantity" : 10,
    "activationDate" : [ 2026, 1, 6, 17, 1, 14, 261476000 ],
    "expirationDate" : [ 2026, 1, 12, 17, 1, 14, 261488000 ],
    "identifier" : "cb03516e-ddd8-4cbb-8c00-2f36518cff4f"
  } ],
  "brandId" : "test-operator"
}

3.4.2. Curl Request

$ curl 'http://localhost:8080/api/v1/free-spins' -i -X POST \
    -H 'x-api-key: 49cba8e8-a848-4a10-991b-405f1992ade7' \
    -H 'x-signature: ebccfc50b758b5fb7137df123b0c5897653fe1a66b74491f4b1d106ef83b1218' \
    -H 'x-timestamp: 1767618074261' \
    -H 'x-nonce: d9080c43-3f78-438c-95f2-51391af5e248' \
    -H 'Content-Type: application/json' \
    -d '{
  "player" : {
    "playerIdentifier" : "player-123",
    "currencyCode" : "FUN"
  },
  "freeSpins" : [ {
    "gameIdentifier" : "western-express",
    "amount" : 10,
    "quantity" : 10,
    "activationDate" : [ 2026, 1, 6, 17, 1, 14, 261476000 ],
    "expirationDate" : [ 2026, 1, 12, 17, 1, 14, 261488000 ],
    "identifier" : "cb03516e-ddd8-4cbb-8c00-2f36518cff4f"
  } ],
  "brandId" : "test-operator"
}'

3.4.3. Example Response

HTTP/1.1 201 Created
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Content-Type: application/json
Content-Length: 35
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 0
Referrer-Policy: no-referrer

{
  "isFreeSpinRegistered" : true
}

3.5. Cancel Free Spin

DELETE /api/v1/free-spins/{id}/{operator}

Cancels an existing free spin.

3.5.1. Example Request

DELETE /api/v1/free-spins/freespin-123/test-operator HTTP/1.1
x-api-key: 49cba8e8-a848-4a10-991b-405f1992ade7
x-signature: 2dc4e3c561b523f1ae77297185e66364a659fb2f758315d8fcf7bd732da23c3e
x-timestamp: 1767618074375
x-nonce: 5a05effe-bfb1-4c96-b73e-cea55bc25db1
Host: localhost:8080

3.5.2. Curl Request

$ curl 'http://localhost:8080/api/v1/free-spins/freespin-123/test-operator' -i -X DELETE \
    -H 'x-api-key: 49cba8e8-a848-4a10-991b-405f1992ade7' \
    -H 'x-signature: 2dc4e3c561b523f1ae77297185e66364a659fb2f758315d8fcf7bd732da23c3e' \
    -H 'x-timestamp: 1767618074375' \
    -H 'x-nonce: 5a05effe-bfb1-4c96-b73e-cea55bc25db1'

3.5.3. Example Response

HTTP/1.1 202 Accepted
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 0
Referrer-Policy: no-referrer

4. Reverse Integration (Gateway → Operator)

These endpoints must be implemented by the Operator. The Gateway will call these endpoints during gameplay.

4.1. Authenticate Session

POST /authenticate

Called by the Gateway after the first session initialization starts to confirm the request and retrieve player details. This callback is only performed if requires_authentication is set to true for the operator.

4.1.1. Request Example

{
  "sessionId" : "e017c447-41b5-4799-8826-9995037dcb2a",
  "transactionUniqueId" : "85553d1a-8ed3-4308-b735-42055aadeb7d",
  "canceledTransactionUniqueId" : "193b0d37-07d2-4eae-8439-628953c5a8ff",
  "playerId" : "7f59b83f-4580-4876-a7d4-ca622907f81f",
  "gameId" : "test-game",
  "roundId" : "9f07d5cb-127c-4c7c-a0fe-0d548c6eeba0",
  "operatorCode" : "TEST_AGGREGATOR_OP",
  "amount" : 100,
  "roundClosed" : false,
  "currencyCode" : "EUR",
  "timestamp" : 1767030561465,
  "gameType" : "CRASH"
}

4.1.2. Curl Request

curl -X POST 'https://operator-api.com/rollback' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -H 'signature: W//IftSDVga1WXc3cv6b4CNx8Qd5TkAlyrYwD5LjFmS+bSOVnZZUHVb2SIahLPmd88t122vGC4zqtQk9PcoVdU7WB2Akh8e/KxWyyq8a6DwJxOdxCndp9UT/40D4aMQ2gZp62iJun9NYG4pME0CS3XxMDMIL0tYN+RMWE3T/0DmbMWH3G7/TCPtpEglzNZAGVS7IVCFuzu1uCF8fAqpmPPMSctbXR10HgL2ZvU3ctiyD2Zu/dl8veJRcXzlPOsFtn9FuJjO9j5YF7pEjIxcXxMBhi8gHU/ag3g4v2oS0zlamrpmBCbwAu3ar/qhYgxQwGqyN8Z9CPlH+8mh3ve+SWg==' \
  -d '{"sessionId":"e017c447-41b5-4799-8826-9995037dcb2a","transactionUniqueId":"85553d1a-8ed3-4308-b735-42055aadeb7d","canceledTransactionUniqueId":"193b0d37-07d2-4eae-8439-628953c5a8ff","playerId":"7f59b83f-4580-4876-a7d4-ca622907f81f","gameId":"test-game","roundId":"9f07d5cb-127c-4c7c-a0fe-0d548c6eeba0","operatorCode":"TEST_AGGREGATOR_OP","amount":100,"roundClosed":false,"currencyCode":"EUR","timestamp":1767030561465,"gameType":"CRASH"}'

4.1.3. Response Example

{
  "playerId" : "player-123",
  "ipAddress" : "127.0.0.1",
  "currencyCode" : "EUR",
  "balance" : 10000,
  "countryCode" : "GE"
}

4.2. Fetch Balance

POST /fetch-balance

Called by the Gateway to retrieve the current balance of a player.

4.2.1. Request Example

{
  "sessionId" : "4042892c-b1ec-4481-ad36-9b792789d9bf",
  "playerId" : "c36d082e-93c7-4cbc-bc2b-5976f660e55c",
  "currencyCode" : "EUR",
  "gameId" : "test-game",
  "timestamp" : 1767618055463
}

4.2.2. Curl Request

curl -X POST 'https://operator-api.com/balance' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -H 'signature: jfJXF4NKbapeUod8MrCsEkcvLctLQZdSksgH71hBjzLrwEfl0099Z4IGRpvyi0qEnLdFwl2ZuOeI7RZE5By3gN/Sai8nRW30ZXsxtYuyfLNoP2+my2U5MgSlgVymyqNk/rW8mysiIvFoqpjd8zqZ+gClgH3y/6p7ID0KkczuZ0L8h2nvQS2l+O283yzCfuqyw/ZYcvx1ctKggiHBCcY3mmyVA+ma+S0hhckApUQZwDeS34Bif82QrjIQ4kTCH59hfGTuPDXn/jSBU+YdtA7FtqmNMsnNKgYlLUsxdwgJgDu6Dd3dkKJSvzVQvi4Td6m1NzpJNASqy6zB9R9EQuT8wQ==' \
  -d '{"sessionId":"4042892c-b1ec-4481-ad36-9b792789d9bf","playerId":"c36d082e-93c7-4cbc-bc2b-5976f660e55c","currencyCode":"EUR","gameId":"test-game","timestamp":1767618055463}'

4.2.3. Response Example

{
  "currencyCode" : "EUR",
  "balance" : 10000
}

4.3. Place Bet

POST /place-bet

Called by the Gateway when a player places a bet.

4.3.1. Request Example

{
  "operatorCode" : "TEST_AGGREGATOR_OP",
  "sessionId" : "4042892c-b1ec-4481-ad36-9b792789d9bf",
  "transactionUniqueId" : "38b1d6a6-f540-44b0-9011-330597d7f624",
  "playerId" : "c36d082e-93c7-4cbc-bc2b-5976f660e55c",
  "gameId" : "test-game",
  "roundId" : "774eaac3-d9cc-4478-8daa-e530bf13593a",
  "amount" : 200,
  "currencyCode" : "EUR",
  "winType" : "ORDINARY",
  "betId" : "08832038-b572-46e7-8256-d982f21a3c2b",
  "timestamp" : 1767618055783,
  "roundClosed" : true,
  "gameType" : "CRASH"
}

4.3.2. Curl Request

curl -X POST 'https://operator-api.com/deposit' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -H 'signature: P6Nl5F0novcNfme6c04kzHiZFNFsgmW+N25554QSA8bWmyRK2hj8LF9+3M4wFk11rlDSVGvXt47eBJZ776aiHIou5ateV17GLLmTx+s9+vspvOkjtM8I/NjmYI/oZi9EonQHwrm49xvU00iMBJdBYiZrTISmChybzdUJvhUHH8eGcGdTUmcaf2okRUZV+i1rsnlpHviwxKGvWuh5WiU/3OcbsJd6rxNyffXcKMJH8ckb49JfvO9ZRScAmGMDDVhy6lPSFdtTNK3sCXOcBxcVqsjstddHISm+jK1PD0NNEeGzCW26DEmzKrT+SgvM64NTyxy8Tzlz2T36m5RTuxv8wQ==' \
  -d '{"operatorCode":"TEST_AGGREGATOR_OP","sessionId":"4042892c-b1ec-4481-ad36-9b792789d9bf","transactionUniqueId":"38b1d6a6-f540-44b0-9011-330597d7f624","playerId":"c36d082e-93c7-4cbc-bc2b-5976f660e55c","gameId":"test-game","roundId":"774eaac3-d9cc-4478-8daa-e530bf13593a","amount":200,"currencyCode":"EUR","winType":"ORDINARY","betId":"08832038-b572-46e7-8256-d982f21a3c2b","timestamp":1767618055783,"roundClosed":true,"gameType":"CRASH"}'

4.3.3. Response Example

{
  "transactionId" : "e6bcff3e-3abb-43cc-9d7f-6910d3099800",
  "balance" : 9900
}

4.4. Declare Win

POST /declare-win

Called by the Gateway when a player wins a round.

4.4.1. Request Example

{
  "operatorCode" : "TEST_AGGREGATOR_OP",
  "sessionId" : "4042892c-b1ec-4481-ad36-9b792789d9bf",
  "transactionUniqueId" : "38b1d6a6-f540-44b0-9011-330597d7f624",
  "playerId" : "c36d082e-93c7-4cbc-bc2b-5976f660e55c",
  "gameId" : "test-game",
  "roundId" : "774eaac3-d9cc-4478-8daa-e530bf13593a",
  "amount" : 200,
  "currencyCode" : "EUR",
  "winType" : "ORDINARY",
  "betId" : "08832038-b572-46e7-8256-d982f21a3c2b",
  "timestamp" : 1767618055783,
  "roundClosed" : true,
  "gameType" : "CRASH"
}

4.4.2. Curl Request

curl -X POST 'https://operator-api.com/deposit' \
  -H 'accept: */*' \
  -H 'Content-Type: application/json' \
  -H 'signature: P6Nl5F0novcNfme6c04kzHiZFNFsgmW+N25554QSA8bWmyRK2hj8LF9+3M4wFk11rlDSVGvXt47eBJZ776aiHIou5ateV17GLLmTx+s9+vspvOkjtM8I/NjmYI/oZi9EonQHwrm49xvU00iMBJdBYiZrTISmChybzdUJvhUHH8eGcGdTUmcaf2okRUZV+i1rsnlpHviwxKGvWuh5WiU/3OcbsJd6rxNyffXcKMJH8ckb49JfvO9ZRScAmGMDDVhy6lPSFdtTNK3sCXOcBxcVqsjstddHISm+jK1PD0NNEeGzCW26DEmzKrT+SgvM64NTyxy8Tzlz2T36m5RTuxv8wQ==' \
  -d '{"operatorCode":"TEST_AGGREGATOR_OP","sessionId":"4042892c-b1ec-4481-ad36-9b792789d9bf","transactionUniqueId":"38b1d6a6-f540-44b0-9011-330597d7f624","playerId":"c36d082e-93c7-4cbc-bc2b-5976f660e55c","gameId":"test-game","roundId":"774eaac3-d9cc-4478-8daa-e530bf13593a","amount":200,"currencyCode":"EUR","winType":"ORDINARY","betId":"08832038-b572-46e7-8256-d982f21a3c2b","timestamp":1767618055783,"roundClosed":true,"gameType":"CRASH"}'

4.4.3. Response Example

{
  "transactionId" : "81e86121-4fb2-43ef-9927-1eddf53047d6",
  "balance" : 10200
}